Skip to content

Support AWS RDS IAM Authentication for Redash database - #7694

Open
winebarrel wants to merge 9 commits into
getredash:masterfrom
winebarrel:support-rds-iam-auth-for-redash-db
Open

Support AWS RDS IAM Authentication for Redash database#7694
winebarrel wants to merge 9 commits into
getredash:masterfrom
winebarrel:support-rds-iam-auth-for-redash-db

Conversation

@winebarrel

@winebarrel winebarrel commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • Refactor
  • Feature
  • Bug Fix
  • New Query Runner (Data Source)
  • New Alert Destination
  • Other

Description

This will enable the use of AWS RDS IAM authentication with Redash Database.
see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html

Using IAM authentication allows you to connect to the database more securely than with password authentication.

How is this tested?

  • Unit tests (pytest, jest)
  • E2E Tests (Cypress)
  • Manually
  • N/A

I added the following settings and confirmed that I could connect to the RDS for testing.

  • compose.yaml
  # REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
  REDASH_DATABASE_URL: "postgresql://iam_user@database-1.cluster-xxx.ap-northeast-1.rds.amazonaws.com/postgres"
  AWS_DEFAULT_REGION: ap-northeast-1
  REDASH_DATABASE_AWS_IAM_AUTH: "true"
  • .env
# NOTE: It is not a required environment variable.
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...

スクリーンショット 2026-04-17 13 29 40スクリーンショット 2026-04-17 13 32 58

postgres=> select * from pg_stat_activity where usename = 'iam_user';
-[ RECORD 1 ]----+------------------------------
datid            | 5
datname          | postgres
pid              | 4432
leader_pid       |
usesysid         | 16455
usename          | iam_user
application_name |
client_addr      | xxx.xxx.xxx.xxx
client_hostname  |
client_port      | 55457
backend_start    | 2026-04-17 04:31:30.253999+00
xact_start       |
query_start      | 2026-04-17 04:34:25.004999+00
state_change     | 2026-04-17 04:34:25.005079+00
wait_event_type  | Client
wait_event       | ClientRead
state            | idle
backend_xid      |
backend_xmin     |
query_id         |
query            | ROLLBACK
backend_type     | client backend
-[ RECORD 2 ]----+------------------------------
datid            | 5
...

Related Tickets & Documents

Mobile & Desktop Screenshots/Recordings (if there are UI changes)

N/A

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

@winebarrel
winebarrel force-pushed the support-rds-iam-auth-for-redash-db branch from 584229f to 3cb352b Compare April 18, 2026 04:26
- upstream migrated Poetry -> uv (removed poetry.lock, added uv.lock)
- moved boto3/botocore from all_ds group to main [project].dependencies
- regenerated uv.lock
@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds opt-in support for AWS RDS IAM authentication for Redash's own metadata database (not for query runner data sources), controlled by the REDASH_DATABASE_AWS_IAM_AUTH environment variable.

  • A module-level boto3.client("rds") singleton (_RDS_CLIENT) is created once when IAM auth is enabled, and a SQLAlchemy do_connect listener on the Engine class injects a freshly generated IAM token as the connection password for every new physical connection.
  • The boto3 import is guarded inside the if settings.REDASH_DATABASE_AWS_IAM_AUTH block, keeping it optional (installed via the all_ds extras) so non-AWS deployments are unaffected.
  • The version bump in uv.lock reflects the feature addition (26.7.0.dev026.8.0.dev0).

Confidence Score: 5/5

  • Safe to merge — the change is narrow and opt-in, touching only the metadata DB connection path when REDASH_DATABASE_AWS_IAM_AUTH=true.
  • The implementation is clean: the boto3 client is created once as a module-level singleton, the do_connect hook correctly injects a fresh IAM token only at physical connection time (not on pool checkout), and the import is properly lazy-guarded so non-AWS installs are unaffected. All concerns raised in earlier review rounds have been resolved or consciously accepted with documented rationale.
  • No files require special attention.

Important Files Changed

Filename Overview
redash/models/base.py Adds the IAM auth hook: a module-level RDS client singleton and a do_connect listener that injects a fresh token as the password on each new physical connection. Boto3 import is correctly lazy-guarded. SSL handling is intentionally left to the operator per project policy.
redash/settings/init.py Adds REDASH_DATABASE_AWS_IAM_AUTH boolean setting parsed from the REDASH_DATABASE_AWS_IAM_AUTH env var, defaulting to false. Clean, minimal addition.
uv.lock Lock file updated to reflect the version bump from 26.7.0.dev0 to 26.8.0.dev0. No dependency changes introduced.

Sequence Diagram

sequenceDiagram
    participant App as Redash App
    participant SQA as SQLAlchemy Pool
    participant Hook as do_connect Hook
    participant RDS_API as AWS RDS API
    participant DB as RDS PostgreSQL

    App->>SQA: Request DB connection
    SQA->>Hook: do_connect event (new physical connection)
    Hook->>RDS_API: generate_db_auth_token(host, port, user)
    RDS_API-->>Hook: IAM auth token (valid 15 min)
    Hook->>Hook: "cparams["password"] = token"
    SQA->>DB: "psycopg2.connect(..., password=token)"
    DB-->>SQA: Connection established
    SQA-->>App: Pooled connection returned
Loading

Reviews (8): Last reviewed commit: "Merge branch 'master' into support-rds-i..." | Re-trigger Greptile

Comment thread redash/models/base.py
Comment thread redash/models/base.py Outdated
Comment thread pyproject.toml Outdated
boto3.client("rds") was instantiated inside the do_connect hook, so a new
client (endpoint resolution, credential chain lookup, config parsing) was
built on every physical DB connection. Hoist it to a module-level RDS_CLIENT
singleton and close over it, leaving only generate_db_auth_token per connection.
Comment thread redash/models/base.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="redash/models/base.py">

<violation number="1" location="redash/models/base.py:49">
P1: RQ worker jobs inherit this boto3 client across forks, which can cause incorrect response ordering and intermittent RDS token-generation or database-connection failures. Creating the client lazily after the fork (or otherwise once per worker process) preserves the connection reuse without sharing a client across processes.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread redash/models/base.py Outdated
RDS IAM DB authentication requires the token to be sent over an encrypted
channel. Default sslmode to 'require' in the do_connect hook (via setdefault,
so an operator-configured stricter mode like verify-full is preserved).

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="redash/models/base.py">

<violation number="1" location="redash/models/base.py:61">
P1: IAM authentication can still attempt a non-encrypted connection when `REDASH_DATABASE_URL` specifies `sslmode=disable` (or another non-strict mode), because `setdefault` only handles a missing key. Preserve only `verify-ca`/`verify-full`; set every other value to `require`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread redash/models/base.py Outdated
Instead of promoting boto3/botocore to top-level dependencies (which adds the
full AWS SDK to every install), keep them in the optional all_ds group and
import boto3 lazily inside the REDASH_DATABASE_AWS_IAM_AUTH guard. Enabling IAM
auth now requires installing the all_ds extras (or boto3 directly).
setdefault only covered a missing sslmode, so an explicit weak mode in
REDASH_DATABASE_URL (e.g. sslmode=disable/prefer) would let IAM auth attempt an
unencrypted connection. Force sslmode=require for anything other than the
stricter verify-ca/verify-full.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pyproject.toml">

<violation number="1">
P2: With boto3 moved out of the core dependencies, a base (non-all_ds) install enabling REDASH_DATABASE_AWS_IAM_AUTH will crash at startup with a bare ImportError, because base.py imports boto3 unguarded. The Postgres/Athena runners guard the same import with try/except (IAM_ENABLED flag), so consider guarding base.py's import too and failing with a clear message (or requiring all_ds) instead of a hard crash.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Don't force sslmode in the do_connect hook. SSL is not an intrinsic requirement
of IAM auth (it's controlled server-side by rds.force_ssl), sslmode is static
connection config rather than something the hook needs to set, and forcing it
would override an operator's explicit choice. Leave transport security to the
DB URL and rds.force_ssl.
It's an internal detail of the connection hook with no external references;
mark it private to match the file's convention (e.g. _gfk_types).
@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Want your agent to iterate on Greptile's feedback? Try greploops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant