Skip to content

Support AWS RDS IAM Authentication for Redash database - #7694

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

winebarrel wants to merge 10 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 AWS RDS IAM authentication support for Redash's own metadata database, controlled by the REDASH_DATABASE_AWS_IAM_AUTH environment variable. Previous review iterations addressed the main concerns: boto3 is imported lazily inside the feature guard, the RDS client is a module-level singleton (not re-created per connection), SSL enforcement was intentionally omitted per team policy, and boto3/botocore remain in the optional all_ds dependency group rather than being promoted to required deps.

  • redash/settings/__init__.py: Adds REDASH_DATABASE_AWS_IAM_AUTH boolean setting defaulting to false, with a link to the AWS IAM DB auth documentation.
  • redash/models/base.py: When the setting is enabled, registers a SQLAlchemy do_connect event listener that calls generate_db_auth_token (a local signing operation — no extra network round-trip) and injects the result as the connection password on each new physical connection.
  • uv.lock: Package version bump from 26.7.0.dev0 to 26.8.0.dev0; no new top-level dependencies introduced.

Confidence Score: 5/5

  • Safe to merge. The feature is fully opt-in (disabled by default), the implementation is straightforward, and all substantive concerns from prior review rounds have been resolved.
  • The change is small and well-scoped: a new boolean setting wired to a conditional block that lazily imports boto3, creates one client singleton, and registers a single event hook. It is off by default, so it has zero impact on deployments that don't set the env var. Previous feedback on client lifecycle, dependency footprint, and SSL behavior has all been addressed.
  • No files require special attention.

Important Files Changed

Filename Overview
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 addition with a documentation link.
redash/models/base.py Adds a conditional IAM auth block: lazily imports boto3, creates a module-level RDS client singleton, and registers a SQLAlchemy do_connect event listener that injects a fresh IAM auth token as the password on each new physical connection. Previous review concerns (per-connection client creation, SSL enforcement, dependency footprint) have all been addressed.
uv.lock Version bump only: redash 26.7.0.dev0 → 26.8.0.dev0. No new top-level dependencies added; boto3/botocore remain in the optional all_ds group.

Sequence Diagram

sequenceDiagram
    participant App as Redash App
    participant SA as SQLAlchemy Engine
    participant Hook as do_connect Hook
    participant RDS as _RDS_CLIENT (boto3)
    participant DB as RDS PostgreSQL

    Note over App: Module load (REDASH_DATABASE_AWS_IAM_AUTH=true)
    App->>RDS: boto3.client("rds") → _RDS_CLIENT singleton

    App->>SA: db.engine.connect()
    SA->>Hook: do_connect(_dialect, _conn_rec, _cargs, cparams)
    Hook->>RDS: generate_db_auth_token(DBHostname, Port, DBUsername)
    Note over RDS: Locally signed presigned URL<br/>(no network call)
    RDS-->>Hook: auth_token (valid 15 min)
    Hook->>Hook: "cparams["password"] = auth_token"
    SA->>DB: "psycopg2.connect(**cparams) with IAM token as password"
    DB-->>SA: Connection established
Loading

Reviews (9): 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