Skip to main content

IAM Authentication for Database

  • Status: accepted
  • Deciders: @dynamike, @pjdufour-truss
  • Date: 2018-10-15

Context and Problem Statement

Rotating passwords to the MyMove database is a multi-step process that requires synchronizing changes among application servers and migrations. AWS now provides an easy solution to outsource authentication for an RDS database to AWS Identity and Access Management (IAM).

https://aws.amazon.com/about-aws/whats-new/2018/09/amazon-rds-postgresql-now-supports-iam-authentication/

The default PostgreSQL authentication method is to use password authentication. A hash of the password is stored internally within the database. There are other external authentication methods that support connecting from the same host machine or require running additional infrastructure, e.g., an LDAP service. However, none of those methods are worth the operational burden for managing authentication for a single application or help with the credential rotation problem.

IAM is the access manager for many AWS services and has a standardized API for the AWS CLI (https://aws.amazon.com/cli/), Terraform (https://www.terraform.io/), and Go SDK (https://docs.aws.amazon.com/sdk-for-go/api/service/iam/). Should we switch to using IAM?

Decision Drivers

  • Easy to rotate passwords or access keys
  • Maximize Dev-prod parity
  • Strong passwords / access keys
  • Works with sqlx, our database driver for PostgreSQL
  • Works with Pop, our ORM-like framework for interacting with our PostgreSQL database
  • Works within our migrations workflow.

Considered Options

  • Internal PostgreSQL Authentication Provider
  • External IAM Authentication Provider

Decision Outcome

Chosen option: "External IAM Authentication Provider".

Pros and Cons of the Options

Internal PostgreSQL Authentication Provider

External IAM Authentication Provider

  • + Credential rotation is handled by AWS. Using the Task Role without any use of static passwords, we can automatically retrieve a valid set of credentials, which are then used to generate an auth token to connect to the database, e.g., authToken, err := rdsutils.BuildAuthToken(host, region, cfg.User, stscreds.NewCredentials(sess, "arn:aws:iam::[AWS ID]:role/SomeRole"))
  • - Different authentication method for development and production.
  • + Following of the Shared Responsibility Model, the AWS IAM service is responsible for generating strong access keys, with the specific hashing algorithm internal to AWS.
  • + rdsutils (github.com/aws/aws-sdk-go/service/rds/rdsutils) provides the ability to generate ephemeral authentication tokens to connect to AWS RDS using IAM (https://docs.aws.amazon.com/sdk-for-go/api/service/rds/rdsutils/)
  • +/- Our database framework Pop (https://github.com/gobuffalo/pop) may support IAM authentication by providing the connection string including the ephemeral access token as a URL string in ConnectionDetails to NewConnection. Hard to know if this will work out of the box without a proof of concept.
  • + As part of a migration, we can enable/disable RDS authentication for a given web application role using GRANT rds_iam TO user_xyz;.