Skip to content

HikariCPDataSourceFactory: Add cross-account assume-role support to native RDS IAM authentication #27552

@bwright86

Description

@bwright86

Problem

The native RDS IAM authentication path introduced in #26231 uses DefaultCredentialsProvider exclusively:

// AwsRdsIamAwareDataSource (inner class of HikariCPDataSourceFactory)
RdsUtilities rdsUtilities = RdsUtilities.builder()
    .credentialsProvider(DefaultCredentialsProvider.create())
    .region(Region.of(awsRegion))
    .build();

This works when the OpenMetadata server and its RDS MySQL backend are in the same AWS account. However, a common enterprise pattern is to isolate databases into a dedicated account — for example, a shared services EKS cluster in account A connecting to an RDS instance in account B. In this topology the pod's IRSA role (account A) cannot sign a valid auth token for an RDS resource in account B. Token generation succeeds client-side but RDS rejects the connection with Access denied because the token is signed by an identity that has no rds-db:connect permission on the target cluster.

The required credential chain is:

Pod IRSA role (account A)
  → sts:AssumeRole → cross-account role (account B)
    → rds:GenerateDbAuthToken (signed by account B)

There is currently no way to express this in the isAwsRdsIamAuth configuration path.

Proposed Solution

Add an optional assumeRoleArn parameter. When present, wrap the base credential chain with StsAssumeRoleCredentialsProvider before generating the auth token.

Required dependency (likely already transitive via the AWS SDK BOM):

software.amazon.awssdk:sts

Implementation sketch:

private AwsCredentialsProvider buildCredentialsProvider(String assumeRoleArn) {
    AwsCredentialsProvider base = DefaultCredentialsProvider.create();
    if (assumeRoleArn == null || assumeRoleArn.isBlank()) {
        return base;
    }
    return StsAssumeRoleCredentialsProvider.builder()
        .stsClient(StsClient.builder()
            .credentialsProvider(base)
            .region(Region.of(awsRegion))
            .build())
        .refreshRequest(AssumeRoleRequest.builder()
            .roleArn(assumeRoleArn)
            .roleSessionName("openmetadata-rds-iam-auth")
            .build())
        .build();
}

Configuration — extend the existing JDBC URL parameter detection or add a dedicated DatabaseConfiguration field parallel to the existing awsRegion extraction logic:

# values.yaml
database:
  dbParams: "awsRegion=us-east-1&allowPublicKeyRetrieval=true&assumeRoleArn=arn:aws:iam::123456789012:role/openmetadata-rds-access"

Environment

  • OpenMetadata: 1.12.4 / 1.12.5 (identical code path)
  • Deployment: EKS cluster in a separate AWS account from the RDS MySQL backend
  • Auth chain needed: Pod IRSA → sts:AssumeRole → cross-account role → rds-db:connect

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