> ## Documentation Index
> Fetch the complete documentation index at: https://ngquct-docs-fix-500-query-results.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS IAM Authentication

> Connect to Amazon RDS and Aurora with IAM database authentication instead of a static password

Set up the AWS side first, or **Test Connection** fails against a user the database never created for IAM.

## On the AWS side

Enable IAM database authentication on the RDS instance or Aurora cluster. MySQL, MariaDB, and PostgreSQL all support it. Then create the database user:

<Tabs>
  <Tab title="MySQL / MariaDB">
    ```sql theme={null}
    CREATE USER 'app_user' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
    ```
  </Tab>

  <Tab title="PostgreSQL">
    ```sql theme={null}
    GRANT rds_iam TO "app_user";
    ```
  </Tab>
</Tabs>

<Warning>
  A user is either password-authenticated or IAM-authenticated, never both. Connecting as a user that still has only a password fails.
</Warning>

## Setting up

In the connection form, set **Authentication** to one of the AWS IAM options. The **Password** field gives way to the AWS fields, and **Username** takes the IAM database user.

<Frame caption="AWS IAM options in the connection form">
  <img className="block dark:hidden" src="https://mintcdn.com/ngquct-docs-fix-500-query-results/hA72m8tSnRe3b-ew/images/aws-iam-authentication-fields.png?fit=max&auto=format&n=hA72m8tSnRe3b-ew&q=85&s=34abf050a6da6e4fefbdab99156c001b" alt="Connection form with Authentication set to AWS IAM (Profile)" width="1560" height="960" data-path="images/aws-iam-authentication-fields.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/ngquct-docs-fix-500-query-results/hA72m8tSnRe3b-ew/images/aws-iam-authentication-fields-dark.png?fit=max&auto=format&n=hA72m8tSnRe3b-ew&q=85&s=6b252b5106b1f9d0a253265636e49938" alt="Connection form with Authentication set to AWS IAM (Profile)" width="1560" height="960" data-path="images/aws-iam-authentication-fields-dark.png" />
</Frame>

| Option                   | Credentials come from                                                                |
| ------------------------ | ------------------------------------------------------------------------------------ |
| **AWS IAM (Access Key)** | An access key ID, secret access key, and optional session token typed into the form  |
| **AWS IAM (Profile)**    | A named profile in `~/.aws/credentials` and `~/.aws/config`                          |
| **AWS IAM (SSO)**        | A profile backed by IAM Identity Center, using the token cache in `~/.aws/sso/cache` |

Pick **AWS IAM (Profile)** if you already use the AWS CLI here: it reads the same files the same way.

**AWS Region** is read from the endpoint when the hostname looks like `mydb.abc123.us-east-1.rds.amazonaws.com`. Fill it in for a CNAME or any other custom endpoint, or to override what was detected.

## Token lifetime

Each connect signs a fresh token, valid for 15 minutes and never written to disk; automatic reconnects sign another. Nothing to paste, rotate, or refresh.

IAM also requires encryption in transit, so an [SSL mode](/connections/ssl) of **Disabled** or **Preferred** is raised to **Required** for the connect.

## Profiles

**Profile Name** lists the profiles found in `~/.aws/config` and `~/.aws/credentials` and accepts a typed name. Blank means `default`. Profiles resolve the way the AWS CLI resolves them:

* Static `aws_access_key_id` / `aws_secret_access_key` pairs.
* `credential_process` commands, so a profile can be backed by SSO, 1Password, or any other credential helper.
* `role_arn` assume-role profiles, resolved through STS. Base credentials come from `source_profile`, chaining up to five deep, or from `credential_source = Environment`. `mfa_serial` is not supported.

For **AWS IAM (SSO)**, run `aws sso login --profile <name>` first. A connect that fails on an expired session offers the browser sign-in.

## Tunnels and port forwards

RDS checks the token against its own hostname and port, so the endpoint it was signed for is what matters, not the address dialed.

A tunnel the app opens needs nothing extra: the token is signed for the **Host** and **Port** in the form, not the loopback address the driver gets.

A forward you run yourself leaves `127.0.0.1` in the form, which names no database. Set **RDS Endpoint** to the real one:

```text theme={null}
mydb.abc123.us-east-1.rds.amazonaws.com:5432
```

The port is optional, falling back to 5432 for PostgreSQL and 3306 for MySQL and MariaDB. The field also covers a CNAME or any alias AWS did not issue, and is honored only when **Host** is loopback or already the same hostname.

## Troubleshooting

### Could not determine an AWS region for "…"

The hostname is not a standard RDS endpoint. Fill in **AWS Region**.

### TablePro cannot sign an RDS token for "…"

The connection points at a port forward the app did not open. Fill in **RDS Endpoint** with the endpoint from the AWS console.

### PAM authentication failed

PostgreSQL reports this and MySQL reports `Access denied` when the token was signed for the wrong endpoint. Check **RDS Endpoint** against the console, including the port.

### Profile "…" was not found

The profile has no static keys, no `credential_process`, and no `role_arn`. Check the name and the contents of `~/.aws/config` and `~/.aws/credentials`.

### AWS SSO Sign-In Required

The cached SSO session expired. Accept the prompt, or run `aws sso login --profile <name>`.

## Other AWS services

The same **Authentication** options reach Amazon ElastiCache ([Redis](/databases/redis)) and Amazon Keyspaces ([Cassandra](/databases/cassandra)), each with fields of its own on those pages.
