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

# Amazon RDS

> Connect 4MINDS to Amazon RDS to browse databases, preview tables, and import relational data as datasets — using IAM Role Federation or Amazon Cognito for AWS auth and RDS IAM Database Authentication for SQL access.

This guide walks you through connecting 4MINDS to Amazon RDS. The connection has **two layers**:

1. **AWS-level authentication** — how 4MINDS discovers which RDS instances exist in your account. Uses **IAM Role Federation** (recommended) or **Amazon Cognito**, both shared with the rest of 4MINDS's AWS integrations.
2. **Database-level authentication** — uses **RDS IAM Database Authentication** to generate short-lived tokens from the same AWS credentials used for instance discovery. No separate database username or password is required.

This two-layer model lets 4MINDS list your RDS fleet and connect to individual databases with a single set of AWS credentials — no long-lived database passwords to manage or rotate.

For the generic IAM Role / Cognito setup (creating the OIDC provider, trust policy, Cognito user pool, etc.), see [AWS Integrations](/aws-integrations). The steps below focus on what's **specific to RDS**.

***

## Supported Database Engines

4MINDS supports database browsing on these RDS engines:

| Engine family       | RDS `Engine` values                          |
| ------------------- | -------------------------------------------- |
| **PostgreSQL**      | `postgres`, `aurora-postgresql`              |
| **MySQL / MariaDB** | `mysql`, `mariadb`, `aurora-mysql`, `aurora` |

Other RDS engines (Oracle, SQL Server, etc.) can still be **listed** in the instance picker, but the database/table browser will return an "unsupported engine" error when you open them.

***

## RDS IAM Permissions Policy

Whichever AWS auth method you use (IAM Role Federation or Cognito), attach this policy to the role:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RDSInstanceDiscovery",
      "Effect": "Allow",
      "Action": [
        "rds:DescribeDBInstances"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RDSIAMDatabaseAuth",
      "Effect": "Allow",
      "Action": "rds-db:connect",
      "Resource": "arn:aws:rds-db:*:*:dbuser:*/*"
    },
    {
      "Sid": "IdentityVerification",
      "Effect": "Allow",
      "Action": "sts:GetCallerIdentity",
      "Resource": "*"
    }
  ]
}
```

| Permission                | Purpose                                                                                                     |
| ------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `rds:DescribeDBInstances` | Lists RDS instances in the connected region so 4MINDS can populate the instance picker                      |
| `rds-db:connect`          | Generates short-lived authentication tokens for direct database connections via IAM Database Authentication |
| `sts:GetCallerIdentity`   | Verifies the connection during **Test Connection**                                                          |

Name the policy something memorable like `4MINDS-RDS-Access` — you'll attach it when creating the IAM role (for Role Federation) or the Cognito authenticated role.

> **Note:** The `rds-db:connect` resource ARN above uses a wildcard for all DB users and instances. To restrict access to specific instances or database users, narrow the resource ARN (e.g., `arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFG/my_iam_user`).

### Least-Privilege: Restricting to Specific Instances

If you want to expose only a subset of your RDS fleet, scope both permissions by ARN:

```json theme={null}
{
  "Effect": "Allow",
  "Action": "rds:DescribeDBInstances",
  "Resource": [
    "arn:aws:rds:us-east-1:123456789012:db:prod-analytics",
    "arn:aws:rds:us-east-1:123456789012:db:prod-reporting"
  ]
},
{
  "Effect": "Allow",
  "Action": "rds-db:connect",
  "Resource": [
    "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFG/fourminds_iam_user",
    "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-HIJKLMN/fourminds_iam_user"
  ]
}
```

### RDS Instance Prerequisites for IAM Database Authentication

Each RDS instance you want 4MINDS to browse must have IAM Database Authentication enabled, and a database user configured for IAM auth:

**PostgreSQL:**

```sql theme={null}
CREATE USER fourminds_iam_user WITH LOGIN;
GRANT rds_iam TO fourminds_iam_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO fourminds_iam_user;
```

**MySQL / MariaDB:**

```sql theme={null}
CREATE USER 'fourminds_iam_user'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
GRANT SELECT ON *.* TO 'fourminds_iam_user'@'%';
```

To enable IAM Database Authentication on an existing instance, see [AWS documentation — Enabling and disabling IAM database authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Enabling.html).

***

## Connection Method 1: IAM Role Federation (Recommended)

Short-lived credentials minted per request through AWS STS — no long-lived AWS keys stored in 4MINDS.

1. Complete the one-time AWS setup in [AWS Integrations → IAM Role Federation](/aws-integrations#connection-method-1-iam-role-federation-recommended) (OIDC provider + IAM role with trust policy).
2. Attach the **RDS IAM policy** above to the role (Role Federation and Cognito can share the same role — just attach both service policies to it if you use multiple AWS integrations).
3. In 4MINDS, open **Integrations** → **Amazon RDS** → click **Configure** (or **Settings** if already connected).
4. Keep the **IAM Role** tab selected.
5. Paste your **IAM Role ARN** (e.g., `arn:aws:iam::123456789012:role/4MINDS-integration-role`).
6. Leave the **External ID** field blank — it is not supported for IAM Role Federation (see [AWS Integrations → Verify the Trust Policy](/aws-integrations#c-verify-the-trust-policy)).
7. Enter your **AWS Region** (e.g., `us-east-1`) — this must match the region of the RDS instances you want to browse.
8. Click **Test Connection** — success shows *"Connection successful! Found N instance(s)."*
9. Click **Save Credentials**.

***

## Connection Method 2: Amazon Cognito

Use this if your organization already authenticates against AWS through Cognito User Pools and Identity Pools.

1. Complete the one-time Cognito setup in [AWS Integrations → Amazon Cognito](/aws-integrations#connection-method-2-amazon-cognito) (User Pool, App Client, Identity Pool, authenticated role).
2. Attach the **RDS IAM policy** above to the Cognito **authenticated role**.
3. In 4MINDS, open **Integrations** → **Amazon RDS** → click **Configure**.
4. Switch to the **Cognito** tab.
5. Fill in **User Pool ID**, **App Client ID**, **App Client Secret** (if configured), **Identity Pool ID**, **Username**, and **Password**.
6. Enter your **AWS Region**.
7. Click **Test Connection**, then **Save Credentials**.

***

## 4MINDS Fields

| Field              | Required        | Notes                                                                                                                            |
| ------------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **AWS Region**     | Yes             | Region where your RDS instances are deployed. Must match the region of your Cognito resources (Cognito method)                   |
| **IAM Role ARN**   | IAM Role method | Role with the RDS IAM policy attached                                                                                            |
| **External ID**    | No              | Not supported for IAM Role Federation — leave blank. `sts:ExternalId` conditions are not accepted by `AssumeRoleWithWebIdentity` |
| **Cognito fields** | Cognito method  | See [AWS Integrations](/aws-integrations#gather-your-cognito-details)                                                            |

***

## Importing Data from RDS

Once connected, open the **Datasets** page and click **Add Source** → **Amazon RDS** (or pick RDS from the data source bar inside an existing dataset). The import wizard walks you through four steps:

### Step 1 — Pick an Instance

4MINDS calls `rds:DescribeDBInstances` in your configured region and shows every instance the role can see, with its engine, engine version, instance class, and status. Use the search box to filter by identifier or engine. Click an instance to continue.

> Instances not in the `available` state are shown with a warning color and may fail to connect in Step 2.

### Step 2 — Connect to the Database

4MINDS uses the same AWS credentials from your integration to generate a short-lived IAM authentication token via `generate_db_auth_token`. No separate database username or password is needed — the connection is established automatically using IAM Database Authentication.

* Authentication tokens are generated per-request and expire after 15 minutes.
* The IAM DB user configured on the instance (see [RDS Instance Prerequisites](#rds-instance-prerequisites-for-iam-database-authentication)) determines what permissions the connection has.
* All connections use SSL, as required by RDS IAM Database Authentication.

### Step 3 — Browse Databases

4MINDS opens a live SQL connection to the instance endpoint using the IAM-generated token and lists user databases. System databases (`rdsadmin`, `mysql`, `information_schema`, `performance_schema`, `sys`) are filtered out.

### Step 4 — Select Tables

Click a database to list its base tables. For each table the browser shows:

* Schema-qualified name (e.g., `public.customers` for Postgres, or just `orders` for MySQL)
* Estimated row count (from `pg_stat_user_tables` / `information_schema.tables`)
* Column count
* On-disk size

Check the tables you want to import and click **Add Tables**. Selected tables are staged into your dataset alongside files from any other source.

### During Import

At import time, 4MINDS runs a bulk fetch on each selected table:

* Up to **50,000 rows** per table (hard cap — larger tables are truncated and flagged).
* **Binary columns** (`BYTEA`, `BLOB`, `VARBINARY`, etc.) are dropped from the export rather than base64-encoded, to keep CSV output reasonable.
* Complex types (JSONB, arrays) are serialized with `json.dumps` into a single cell.
* Timeout is **120 seconds** per table.

Each table lands in your dataset as a UTF-8 CSV with the original column names as headers.

***

## Networking Requirements

RDS instances live inside a VPC. For 4MINDS to open a SQL connection, the instance must be reachable from the 4MINDS backend's outbound network:

* **Security group inbound rule** — allow the database port (5432 for Postgres, 3306 for MySQL/MariaDB) from the 4MINDS backend's public IP or the CIDR range of its egress.
* **Publicly accessible = Yes** is the simplest path for temporary testing; for production, prefer a VPC peering / PrivateLink setup with 4MINDS support.
* **SSL** — All connections use SSL, as required by RDS IAM Database Authentication. Ensure your RDS instance has a valid SSL certificate (AWS-managed certificates work out of the box).

If the SQL connection times out, the browser shows:

> *"Connection timed out. The backend may not be able to reach the RDS endpoint — check VPC / security group rules (inbound port open from the backend's network)."*

***

## Security Model

| Credential                        | Where it lives                       | How long                         |
| --------------------------------- | ------------------------------------ | -------------------------------- |
| AWS IAM Role ARN / Cognito config | 4MINDS database (encrypted metadata) | Until you disconnect             |
| Temporary AWS credentials (STS)   | Request memory only                  | \~1 hour, minted per call        |
| IAM DB authentication token       | Request memory only                  | \~15 minutes, generated per call |

No database passwords are stored or transmitted. Each SQL endpoint (`/instances/{id}/databases`, `/tables`, `/preview`) generates a short-lived IAM authentication token from the existing AWS credentials, opens a short-lived SQLAlchemy engine over SSL, runs one query, and disposes of the engine before returning.

***

## Testing Your Connection

After saving credentials, the **Test Connection** button:

1. Resolves your auth method → AWS credentials (via STS AssumeRoleWithWebIdentity for Role Federation, or Cognito GetCredentialsForIdentity for Cognito).
2. Calls `rds:DescribeDBInstances` with a 15-second timeout.
3. Returns *"Connection successful! Found N instance(s)."* on success.

Database-level IAM authentication is tested when you select an instance in the import wizard — it uses the same AWS credentials to generate an authentication token and verify SQL connectivity.

***

## Troubleshooting

| Issue                                                 | Solution                                                                                                                                                                                                                                |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AccessDenied` on Test Connection                     | The IAM policy isn't attached to the role, or is missing `rds:DescribeDBInstances`                                                                                                                                                      |
| `Invalid Access Key ID` / `Invalid Secret Access Key` | Wrong static credentials (only relevant if using legacy access-keys auth)                                                                                                                                                               |
| `Unrecognized client`                                 | Wrong AWS region, or RDS isn't enabled in that region                                                                                                                                                                                   |
| `Could not resolve RDS endpoint hostname`             | The instance endpoint in the instance list is wrong, or DNS can't resolve it from the backend                                                                                                                                           |
| `Connection timed out` (SQL step)                     | Security group doesn't allow inbound from the 4MINDS backend's egress IP/CIDR                                                                                                                                                           |
| `Connection refused`                                  | Port isn't open on the security group, or the instance isn't `Publicly accessible` and there's no peering                                                                                                                               |
| `Authentication failed`                               | IAM Database Authentication is not enabled on the instance, the IAM DB user doesn't exist, or the IAM policy is missing `rds-db:connect`. See [RDS Instance Prerequisites](#rds-instance-prerequisites-for-iam-database-authentication) |
| `SSL error connecting to RDS`                         | IAM DB auth requires SSL — ensure the instance has a valid certificate. AWS-managed certificates work out of the box                                                                                                                    |
| `RDS engine 'oracle-ee' is not supported`             | Database browsing only works on Postgres / MySQL / MariaDB / Aurora variants. See [Supported Database Engines](#supported-database-engines)                                                                                             |
| Tables list is empty                                  | The database has no base tables, or the master user lacks `SELECT` on `information_schema` / `pg_stat_user_tables`                                                                                                                      |

***

## Disconnecting

To remove the RDS integration:

1. Open **Integrations** → **Amazon RDS** → click **Settings**.
2. Click **Disconnect**.

This deactivates the stored AWS connection metadata on 4MINDS. Your AWS resources (IAM roles, OIDC providers, Cognito pools, policies, and IAM DB users) are untouched — delete them in the AWS Console if they're no longer needed.
