Skip to content

[QUESTION]: Connecting to Amazon RDS with IAM credentials using TypeORM #4724

@achansonjr

Description

@achansonjr

Issue type:

[X] question
[ ] bug report
[ ] feature request
[ ] documentation issue

Database system/driver:

[ ] cordova
[ ] mongodb
[ ] mssql
[ ] mysql / mariadb
[ ] oracle
[X] postgres
[ ] cockroachdb
[ ] sqlite
[ ] sqljs
[ ] react-native
[ ] expo

TypeORM version:

[X] latest
[ ] @next
[ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem:

Other environment considerations.

Postgres instance in AWS RDS, using AWS IAM authentication.
How do I allow users to connect to Amazon RDS with IAM credentials?

Using RDS.Signer we generate a token in our node application at application startup.

  const creds = await credentialProviderChain.resolvePromise();
  const token = await Promise.resolve(getRDSAuthToken(creds));

  const databaseOptions: ConnectionOptions = {
    type: 'postgres',
    host: Environment.AWS_RDS_POSTGRES_HOST,
    port: Environment.AWS_RDS_POSTGRES_PORT,
    username: Environment.AWS_RDS_POSTGRES_USER,
    password: token,
    database: Environment.AWS_RDS_POSTGRES_DATABASE,
    migrationsRun: true,
    ssl: {
      rejectUnauthorized: false,
      ca: readFileSync('/path/to/pemfile/rds-combined-ca-us-gov-bundle.pem').toString(),
    },
    entities: [
      Entity1,
      Entity2,
      Entity3,
      Entity4,
      Entity5,
    ],
    migrations: [
      `${__dirname}/migration/*.js`,
    ],
    logging: 'all',
    logger: 'advanced-console',
    synchronize: false,
  };

const databaseConnection = await createConnection(databaseOptions);
const entity1Repo = databaseConnection.getCustomRepository(Entity1);
const entity2Repo = databaseConnection.getCustomRepository(Entity2);
const entity3Repo = databaseConnection.getCustomRepository(Entity3);
const entity4Repo = databaseConnection.getCustomRepository(Entity4);

So that's our ConnectionOptions object. We are able to connect to the entity, and even have migrations running. So we know that the token that is being generated is providing us an active connection. We pass our repos to the routes that need access to those entities throughout our express app.

According to IAM Database Authentication for MySQL and PostgreSQL:

An authentication token is a unique string of characters that Amazon RDS generates on request. Authentication tokens are generated using AWS Signature Version 4. Each token has a lifetime of 15 minutes. You don't need to store user credentials in the database, because authentication is managed externally using IAM. You can also still use standard database authentication.

What happens next is that after 15 minutes the AWS IAM token generated by RDS.Signer goes away and we don't have a way to refresh the connection in Typeorm, nor in our repositories.

We don't really want to recreate a token every request, but there doesn't seem to be a way to use ephemeral credentials in IAM RDS authentication with Typeorm, as there doesn't seem to be a good location to have Typeorm connection or repositories check to see if their connection is still valid, then regenerate whatever ephemeral credentials that might be necessary.

We can use named user accounts in the RDS Postgres database, but thought it would be nice from a security standpoint to be able to utilize the AWS IAM RDS token generation off of the EC2 ephemeral role capability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions