Skip to content

feat: Add AWS IAM database authentication support for MySQL and PostgreSQL #347

Open

Description

@michielvha

What problem are you facing?

When running provider-sql on EKS to manage Aurora MySQL or Aurora PostgreSQL databases, the only authentication option is static username/password credentials stored in a Kubernetes Secret. AWS Aurora supports IAM database authentication, which allows generating short-lived authentication tokens (15 min TTL) using AWS IAM credentials instead of static passwords.

Combined with EKS Pod Identity or IRSA, this eliminates the need for static database passwords entirely, the provider pod assumes an IAM role and generates tokens at connection time.

This is similar to the Azure AD/Entra ID authentication work in #165 / #166 (MSSQL) and #196 (PostgreSQL), but for AWS.

How could Crossplane help solve your problem?

Add a new AWSIAMAuth credential source to the MySQL and PostgreSQL ProviderConfig, alongside the existing MySQLConnectionSecret / PostgreSQLConnectionSecret sources.

Proposed approach:

  1. A new AWSIAMAuth value for the credentials.source enum in ProviderConfig
  2. The connection secret still provides endpoint, port, and username but no password (the token replaces it at connection time)
  3. An optional region field on the credentials spec, with fallback to the secret's region key, then to the AWS SDK default credential chain
  4. TLS/SSL automatically enforced (required by IAM auth)
  5. Uses aws-sdk-go-v2/feature/rds/auth.BuildAuthToken() for token generation
  6. AWS credentials are discovered automatically from the environment (Pod Identity, IRSA, instance metadata)

Example ProviderConfig:

apiVersion: postgresql.sql.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
  name: aurora-iam
spec:
  credentials:
    source: AWSIAMAuth
    connectionSecretRef:
      namespace: crossplane-system
      name: aurora-conn  # contains endpoint, port, username (no password)
    region: us-east-1    # optional, defaults to AWS SDK chain
  sslMode: require

Scope: This proposal covers provider authentication only; how provider-sql connects to the database. Creating IAM-authenticated database users (e.g., GRANT rds_iam TO myuser for PostgreSQL, IDENTIFIED WITH AWSAuthenticationPlugin for MySQL) would be a separate follow-up, as suggested in the discussion on #196.

Why this fits well architecturally:

  • The provider already creates a fresh connection on every reconcile cycle (stateless), so token expiration (15 min) is a non-issue, a new token is generated each time
  • TLS support already exists for both MySQL and PostgreSQL
  • The ProviderCredentials.Source enum is the natural extension point
  • The actual change to each reconciler's Connect() is minimal: generate token → inject as password → proceed as normal

I'm happy to implement this and submit a PR. Would appreciate feedback on the approach before I start.

Activity

  1. Brightside56 commented on Apr 2, 2026

    @Brightside56

    It would significantly simplified usage of provider for those who is on AWS

  2. kkendzia commented on Apr 22, 2026

    @kkendzia

    I like this and we would appreciate a contribution. What comes to my mind is that you have to modify the database to enable IAM auth. This means initially you need password access to enable IAM Access for specific roles: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html

  3. giepa commented on Jun 9, 2026

    @giepa

    Hi, any progress on this?

  4. michielvha commented on Jun 10, 2026

    @michielvha
    Author

    @giepa starting work on this asap have not had the time unfortunately, got a lot going on IRL atm. I'm hoping to start this weekend.

  5. michielvha commented on Jun 17, 2026

    @michielvha
    Author

    @kkendzia tagging you directly since there's a design question below I'd value your call on (the TLS one).

    Quick progress update, plus one thing I'd like your input on before I open the PR.

    I've got a working prototype of the AWSIAMAuth credential source and tested the whole flow end to end against real RDS instances (MySQL 8.0 and Postgres 16 with IAM auth enabled), using the same drivers the provider already uses (go-sql-driver/mysql and lib/pq). The approach is the one I sketched earlier: a new source enum value, generate a token with aws-sdk-go-v2/feature/rds/auth at Connect() time, inject it as the password. Still keeping the scope to provider auth only, since creating the IAM users themselves already works through the existing Role/Grant resources (#106).

    Two things came out of the testing.

    First, MySQL needs allowCleartextPasswords=true in the DSN. The AWSAuthenticationPlugin uses MySQL's cleartext plugin and go-sql-driver refuses it by default, so the MySQL DSN needs a small change that's only applied on the IAM path. Postgres just needs sslmode=require. That part I'll handle in the PR, just noting it here.

    The thing I'd actually like your opinion on is TLS. RDS server certs chain to Amazon's RDS CA bundle, which isn't in the system trust store, so tls=true for MySQL fails certificate verification (found that one the hard way). There are roughly three ways to get verified TLS working:

    • bundle the Amazon RDS CA (https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem, ~165KB) into the provider and register it. Works out of the box, but it means carrying a cert bundle in-tree that needs refreshing when AWS rotates it.
    • reuse the existing tls: custom mechanism and have the user supply the RDS CA themselves. No vendoring, but more setup on their end.
    • use tls=skip-verify, which encrypts but doesn't verify. That's roughly where lib/pq's sslmode=require already sits on the Postgres side anyway.

    My preference would be to bundle it for MySQL and document the custom-TLS option for anyone who'd rather manage the CA, then keep sslmode=require for Postgres in v1 with verify-full documented as the stricter option. But carrying the CA bundle in the repo felt like something to check on before committing to it. Do you have a preference?

    Last thing, a heads up rather than a question: this pulls in aws-sdk-go-v2/config and feature/rds/auth, which would be the first cloud SDK dependency in the repo. Happy to discuss if that's a concern.

  6. kkendzia commented on Jun 18, 2026

    @kkendzia

    Personally I'm not a big fan of putting the bundle into the provider. I'd handle it like an external dependency and document on how to use it properly. Our teams inject the bundle with trustmanager into their applications and I think that's a nice way to handle it, but shouldn't be a problem to just mount it as a secret. At least you just have to do it once for all instances.

    And thx for the work! Looking forward to it

  7. phmcder commented on Jun 18, 2026

    @phmcder

    I agree with @kkendzia . We do the same thing using trust manager

  8. wesdek commented on Sep 24, 2026

    @wesdek

    Hi maintainers, thanks for the work on AWS IAM database authentication. We’re evaluating provider-sql for managing tenant databases and roles on Aurora PostgreSQL, so this feature is relevant to us.

    Could you share what is still needed before this PR can be merged, and whether there is an approximate timeline? Happy to help test it against Aurora PostgreSQL if that would be useful.

  9. michielvha commented on Oct 16, 2026

    @michielvha
    Author

    @kkendzia PR is ready for review, thanks in advance !

  10. krogon-bt commented on Oct 21, 2026

    @krogon-bt

    Another implementation from my fork: #490

    I is passing e2e tests (coverage added) and i have just deployed it to my cluster.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions