Skip to content

feat(db): add IAM authentication#1807

Open
Thegaram wants to merge 3 commits into
developfrom
feat-db-rds-iam-auth
Open

feat(db): add IAM authentication#1807
Thegaram wants to merge 3 commits into
developfrom
feat-db-rds-iam-auth

Conversation

@Thegaram

@Thegaram Thegaram commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Purpose or design rationale of this PR

This PR adds opt-in AWS RDS/Aurora IAM authentication for Postgres as an alternative to static DSN passwords.

  • When enabled via a new useIAMAuth config flag (default off, so existing behavior is unchanged), services authenticate with short-lived IAM tokens regenerated per connection, eliminating manual DB credential rotation.
  • It's wired into both the gorm (common/database) and sqlx (database) layers via a shared pgx-based connector, fails closed on insecure DSNs (rejects sslmode=disable/prefer/allow and multi-host since the token is the password), and exposes Prometheus metrics for token generation.
  • Requires rds_iam on the DB role and an rds-db:connect IAM policy; see database/README.md.

Deployment steps, for each service connecting to RDS:

  1. Create the new RDS DB service user, and ensure IAM auth is enabled on the instance.
  2. Set up IAM on AWS: Allow rds-db:connect on arn:aws:rds-db:<region>:<account>:dbuser:<db-resource-id>/svc_user. Attach it to the role the pod assumes via IRSA / Pod Identity, and make sure the ServiceAccount is wired so the SDK's default credential chain (and AWS_REGION) resolve in-cluster.
  3. Update the service configuration: set useIAMAuth and awsRegion, drop the password from the DSN and add sslmode=require.
  4. Deploy.

Summary by CodeRabbit

  • New Features

    • Added AWS RDS IAM authentication support for database connections (token-based auth as an alternative to static passwords).
    • Added Prometheus instrumentation for IAM token generation and failures.
    • Added conditional connection behavior so IAM auth is used when enabled in configuration.
  • Documentation

    • Documented how to configure useIAMAuth and awsRegion, including required TLS/sslmode and IAM setup steps.
  • Tests

    • Added coverage for IAM authentication connector validation (DSN parsing, TLS enforcement, and region resolution).
  • Chores

    • Updated version to v4.7.15.
    • Refreshed AWS SDK and related dependencies.

@Thegaram Thegaram requested review from georgehao and kchangn June 15, 2026 19:09
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eceb06d6-fa4d-48ed-8739-d070df4e8264

📥 Commits

Reviewing files that changed from the base of the PR and between 48a9669 and 935ff0f.

📒 Files selected for processing (1)
  • common/version/version.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • common/version/version.go

📝 Walkthrough

Walkthrough

Adds optional AWS RDS IAM authentication to the common/database and database packages. A new rdsIAMConnector mints per-connection IAM tokens, enforces TLS, and records Prometheus metrics. Both config structs gain IAM fields, and DB initialization branches on them.

Changes

AWS RDS IAM Authentication

Layer / File(s) Summary
Config contracts: UseIAMAuth and AWSRegion fields
common/database/config.go, database/config.go
Both Config and DBConfig gain UseIAMAuth and AWSRegion fields with JSON tags and inline documentation.
RDS IAM connector and Prometheus metrics
common/database/iam.go, common/database/iam_metrics.go
NewRDSIAMConnector parses the DSN, loads AWS credentials, enforces TLS and single-host DSNs, and returns a driver.Connector. Connect mints a fresh RDS IAM token per connection and updates Prometheus metrics for token count, failures, and duration.
GORM and sqlx DB init wiring
common/database/db.go, database/orm_factory.go
InitDB delegates dialector creation to newDialector, which calls NewRDSIAMConnector when UseIAMAuth is set. NewOrmFactory delegates to openDB, which similarly branches to sqlx.NewDb(sql.OpenDB(connector)) for IAM auth or sqlx.Open otherwise.
Tests, documentation, and module updates
common/database/iam_test.go, database/README.md, common/go.mod, common/version/version.go
TestNewRDSIAMConnector covers DSN parsing, port defaulting, TLS rejection, multi-host rejection, unresolvable region, and invalid DSN errors. README gains an IAM auth section with config example and permission requirements. AWS SDK v2 and pgx/v5 are promoted to direct dependencies; version bumped to v4.7.15.

Sequence Diagram

sequenceDiagram
  participant App
  participant newDialector as newDialector / openDB
  participant NewRDSIAMConnector
  participant rdsIAMConnector as rdsIAMConnector.Connect
  participant BuildAuthToken as rds/auth.BuildAuthToken
  participant pgxstdlib as pgx stdlib

  App->>newDialector: InitDB(config) / NewOrmFactory(cfg)
  newDialector->>NewRDSIAMConnector: dsn, awsRegion
  NewRDSIAMConnector-->>newDialector: connector (driver.Connector)
  newDialector->>App: dialector / *sqlx.DB (via sql.OpenDB)

  App->>rdsIAMConnector: Connect(ctx) [per connection]
  rdsIAMConnector->>BuildAuthToken: endpoint, region, user, creds
  BuildAuthToken-->>rdsIAMConnector: IAM token (password)
  rdsIAMConnector->>pgxstdlib: Connect(ctx) with token injected
  pgxstdlib-->>App: driver.Conn
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hop-hop, the password fades away,
IAM tokens light the database way.
TLS stays on, and metrics ring,
New regions sign what the bunnies bring.
v4.7.15 now dances bright ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is conventional, concise, and accurately summarizes the new IAM auth feature.
Description check ✅ Passed The PR description covers purpose, behavior, and deployment steps, but it omits the template's PR title, deployment-tag, and breaking-change sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-db-rds-iam-auth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

codecov-commenter commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 59.40594% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.43%. Comparing base (1904f82) to head (935ff0f).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
common/database/iam.go 62.26% 18 Missing and 2 partials ⚠️
database/orm_factory.go 0.00% 12 Missing ⚠️
common/database/db.go 43.75% 8 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1807      +/-   ##
===========================================
+ Coverage    35.31%   35.43%   +0.12%     
===========================================
  Files          260      262       +2     
  Lines        22426    22523      +97     
===========================================
+ Hits          7920     7982      +62     
- Misses       13677    13710      +33     
- Partials       829      831       +2     
Flag Coverage Δ
common 31.49% <67.41%> (+2.42%) ⬆️
coordinator 28.56% <ø> (+0.06%) ⬆️
database 36.24% <0.00%> (-1.49%) ⬇️
rollup 35.11% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
common/database/iam_test.go (1)

12-91: ⚡ Quick win

Missing test for DSN without database user.

The NewRDSIAMConnector function validates that the DSN specifies a database user (iam.go line 39); however, the test suite does not cover this error path. All DSNs in the tests include an explicit user.

✅ Proposed test case to add
 	t.Run("rejects invalid dsn", func(t *testing.T) {
 		_, err := NewRDSIAMConnector(ctx, "::not a dsn::", "us-east-1")
 		assert.Error(t, err)
 	})
+
+	t.Run("rejects dsn without user", func(t *testing.T) {
+		// IAM token signature includes the user; a missing user prevents token generation.
+		_, err := NewRDSIAMConnector(ctx,
+			"postgres://mydb.example.rds.amazonaws.com:5432/scroll?sslmode=require",
+			"us-east-1")
+		assert.ErrorContains(t, err, "user")
+	})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@common/database/iam_test.go` around lines 12 - 91, Add a new test case in
TestNewRDSIAMConnector that verifies the function properly rejects DSNs without
a database user. Create a t.Run subtest (similar to the existing ones like
"rejects invalid dsn") that calls NewRDSIAMConnector with a valid DSN format but
with no user specified (for example, a DSN like
"postgres://mydb.example.rds.amazonaws.com:5432/scroll?sslmode=require"), and
verify that the function returns an error, ensuring the validation mentioned in
iam.go line 39 is properly tested.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@common/database/iam_test.go`:
- Around line 12-91: Add a new test case in TestNewRDSIAMConnector that verifies
the function properly rejects DSNs without a database user. Create a t.Run
subtest (similar to the existing ones like "rejects invalid dsn") that calls
NewRDSIAMConnector with a valid DSN format but with no user specified (for
example, a DSN like
"postgres://mydb.example.rds.amazonaws.com:5432/scroll?sslmode=require"), and
verify that the function returns an error, ensuring the validation mentioned in
iam.go line 39 is properly tested.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e2d94c19-781f-4579-8caf-b2104c1afcdc

📥 Commits

Reviewing files that changed from the base of the PR and between 1904f82 and 48a9669.

⛔ Files ignored due to path filters (1)
  • common/go.sum is excluded by !**/*.sum
📒 Files selected for processing (10)
  • common/database/config.go
  • common/database/db.go
  • common/database/iam.go
  • common/database/iam_metrics.go
  • common/database/iam_test.go
  • common/go.mod
  • common/version/version.go
  • database/README.md
  • database/config.go
  • database/orm_factory.go

georgehao
georgehao previously approved these changes Jun 16, 2026
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.

3 participants