Skip to content

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

@michielvha

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions