> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PostgreSQL accounts

> Give people and agents access to a PostgreSQL database without sharing its credentials.

A PostgreSQL [account](https://infisical.com/docs/documentation/platform/pam/accounts/overview.md) stores the credentials for one PostgreSQL database user. Members connect to the database in the browser or through the Infisical CLI, and Infisical records every query they run.

The account can sign in with a password, or with [AWS IAM authentication](#aws-iam-authentication) if the database runs on Amazon RDS or Aurora.

## Prerequisites

* The Admin [role](https://infisical.com/docs/documentation/platform/pam/concepts/access-control.md) on the [folder](https://infisical.com/docs/documentation/platform/pam/folders/overview.md) you'll add the account to
* A [gateway](https://infisical.com/docs/documentation/platform/gateways/overview.md) that can reach the database
* A PostgreSQL [account template](https://infisical.com/docs/documentation/platform/pam/templates/overview.md)

## Create the account

**Step 1**

Go to **Privileged Access Management** > **Accounts** and select **Add Account**.

**Step 2**

Select the **Folder** and a PostgreSQL **Account Template**, then select **Next**.

**Step 3**

Enter a **Name** and the connection details:

| Field | Description |
| - | - |
| **Host** | The database's hostname or IP address |
| **Port** | The database's port (defaults to `5432`) |
| **Database** | The database that sessions connect to |
| **SSL Enabled** | Whether to connect over TLS |
| **Reject Unauthorized** | Whether to reject a server certificate that can't be verified (shown when **SSL Enabled** is on) |
| **SSL Certificate** | The CA certificate that signed the server's certificate (shown when **SSL Enabled** is on) |

If you have a connection string, such as `postgresql://user:password@host:5432/database`, paste it into **Host**. Infisical fills in the other fields from the connection string, including the credentials.

**Step 4**

Select the **Auth Method** and enter the credentials:

> [tab] Password
>
> | Field | Description |
> | - | - |
> | **Username** | The PostgreSQL user |
> | **Password** | The user's password |

> [tab] AWS IAM (RDS / Aurora)
>
> Set up [AWS IAM authentication](#aws-iam-authentication) first.
>
> | Field | Description |
> | - | - |
> | **Username** | The database user that has the `rds_iam` role |
> | **AWS Region** | The region of the RDS instance or Aurora cluster, such as `us-east-1` |
> | **Role ARN** | The IAM role that Infisical assumes to generate an authentication token |

**Step 5**

Select **Create**.

## AWS IAM authentication

With AWS IAM authentication, Infisical doesn't store a password for the database user. Instead, Infisical assumes an IAM role in your AWS account and uses it to generate a short-lived authentication token for each connection.

Set up the database and the IAM role before you create the account:

**Step 1**

In the RDS console, turn on **IAM database authentication** for the RDS instance or Aurora cluster.

**Step 2**

Create the database user and grant it the `rds_iam` role:

```sql theme={"dark"}
CREATE USER app_user WITH LOGIN;
GRANT rds_iam TO app_user;
```

**Step 3**

Create an IAM role with the following trust policy:

```json theme={"dark"}
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::<INFISICAL_AWS_ACCOUNT_ID>:root" },
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": { "sts:ExternalId": "<YOUR_INFISICAL_ORG_ID>" }
    }
  }]
}
```

Replace the placeholders:

* `<INFISICAL_AWS_ACCOUNT_ID>`: `381492033652` for Infisical Cloud (US), `345594589636` for Infisical Cloud (EU), or the ID of the AWS account that runs your instance if you self-host Infisical
* `<YOUR_INFISICAL_ORG_ID>`: your organization ID, which the tooltip on the **Role ARN** field shows

The `sts:ExternalId` condition stops other Infisical organizations from using your role, so don't remove it.

**Step 4**

Attach a policy to the role that lets it connect as the database user:

```json theme={"dark"}
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "rds-db:connect",
    "Resource": "arn:aws:rds-db:<REGION>:<AWS_ACCOUNT_ID>:dbuser:<DB_RESOURCE_ID>/app_user"
  }]
}
```

`<DB_RESOURCE_ID>` is the instance's resource ID, which starts with `db-`, not the instance's name. The RDS console shows the resource ID on the instance's **Configuration** tab.

When you create the account, set the following fields:

* **Host**: the endpoint of the RDS instance or Aurora cluster, not a CNAME or other alias, because AWS signs each token for that exact endpoint
* **SSL Enabled**: always on, because IAM authentication requires TLS
* **SSL Certificate**: to verify the server, turn on **Reject Unauthorized** and paste the RDS certificate bundle for your region, such as `https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem`

Accounts that use AWS IAM have no stored password, so [credential rotation](https://infisical.com/docs/documentation/platform/pam/credential-rotation/overview.md) doesn't apply to them.

If a session fails with `PAM authentication failed for user`, AWS rejected the token. Check that the `rds-db:connect` resource ARN uses the instance's current resource ID, the right region, and the same database user as the account.

## Connect

To open a session, follow [Connect to an account](https://infisical.com/docs/documentation/platform/pam/accounts/connect.md).

> [tab] Browser
>
> The browser session has a table browser, where you can view, filter, edit, and export rows, and a SQL editor for running queries.

> [tab] CLI
>
> Start the local proxy:
>
> ```bash theme={"dark"}
> infisical pam access backend-team/orders-db
> ```
>
> The proxy keeps running in that terminal and prints its port. In a second terminal, connect your PostgreSQL client to that port:
>
> ```bash theme={"dark"}
> psql "postgresql://localhost:<port>/orders"
> ```
>
> The proxy signs in for you, so `psql` doesn't need a password.

## Next steps

> [card] [PostgreSQL credential rotation](https://infisical.com/docs/documentation/platform/pam/credential-rotation/postgresql.md)
>
> Rotate the passwords of PostgreSQL accounts.

> [card] [Sessions](https://infisical.com/docs/documentation/platform/pam/sessions/overview)
>
> Review and end the connections that people and agents make to your accounts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.