• Task
  • Version ยท 6.0
  • Create

Connect to AWS Aurora or Amazon RDS using IAM authentication

Last updated: September 29, 2026

Liquibase Secure can authenticate to Amazon RDS and Aurora databases with a short-lived AWS IAM token instead of a static password. This works with PostgreSQL and MySQL on both RDS and Aurora, and supports cross-account access through AWS STS role assumption.

Before you begin

Be sure you have the following:

  • Liquibase Secure 6.0 or later with the Liquibase AWS extension installed

  • IAM database authentication enabled on your RDS instance or Aurora cluster. It is disabled by default

  • A database user mapped to IAM. On PostgreSQL, grant the rds_iam role to the user. On MySQL, create the user with IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'. For Aurora, see Creating a database account using IAM authentication in the Amazon Aurora User Guide

  • An SSL connection, which IAM authentication always requires. You do not need to turn SSL on at the database, because Amazon RDS and Aurora support it by default and RDS for PostgreSQL expects clients to use it. You request SSL from the client side in Step 3, and Liquibase fails before connecting if the JDBC URL does not ask for it. To require SSL at the database as well, see Using SSL with a PostgreSQL DB instance for the rds.force_ssl parameter, or Encrypting client connections with SSL/TLS to MySQL DB instances for require_secure_transport

  • AWS credentials resolvable through the default credentials provider chain. Java system properties, environment variables, a shared credentials file, an AWS SSO profile, and Amazon ECS and EC2 instance roles are all supported

  • An IAM identity with the rds-db:connect permission on the target database, granted through an IAM policy for IAM database access. The database user name in the policy resource ARN must match the database user name exactly, including case

  • For cross-account access, source credentials with sts:AssumeRole permission and a role ARN whose trust policy allows your source principal and which itself carries rds-db:connect

Procedure

1

Configure IAM authentication

IAM authentication needs an explicit opt-in, an AWS region, a connection that requests SSL, and a password value of aws-rds-iam. There are several ways to provide them.

Be sure to:

  • Replace your_region with the AWS region hosting your database. For example, us-east-1

  • Replace your_database_type with postgresql or mysql

  • Replace your_hostname with your database endpoint. For example, mydb.abc123.us-east-1.rds.amazonaws.com

  • Replace your_port with your database port. For example, 5432 for PostgreSQL or 3306 for MySQL

  • Replace your_database with the name of your database. For example, lbcat

  • Replace your_ssl_parameter with sslmode=require for PostgreSQL, or sslMode=REQUIRED for MySQL

  • Replace your_username with the database user you mapped to IAM. For example, liquibase_iam_test

Note: SSL parameter names are case-sensitive and differ between engines. PostgreSQL uses sslmode and MySQL uses sslMode. A mis-cased name is rejected, because the JDBC driver ignores it and the token would then travel unencrypted. PostgreSQL also accepts verify-ca and verify-full. MySQL also accepts VERIFY_CA and VERIFY_IDENTITY, or useSSL=true paired with requireSSL=true. A bare useSSL=true is rejected, because Connector/J treats it as sslMode=PREFERRED, which allows an unencrypted downgrade.

loading

loading

loading

loading
2

(Optional) Assume a role for cross-account access

Complete this step only if your database lives in a different AWS account than the credentials running Liquibase, or if the rds-db:connect permission is attached to a role rather than to your own identity.

Liquibase assumes the role through AWS STS and uses the resulting credentials to generate the IAM token.

Be sure to:

  • Replace your_role_arn with the ARN of the role to assume. For example, arn:aws:iam::123456789012:role/liquibase-rds-connect

liquibase.aws.roleArn: your_role_arn

To label the STS session, set liquibase.aws.sessionName. The default is liquibase-rds-iam.

3

(Optional) Use a different authentication mechanism for a reference database

Complete this step only if you run diff or diff-changelog and the two databases authenticate differently. A common case is a production target on IAM authentication and a legacy or short-lived reference database still using a password.

By default the reference connection inherits the primary authentication mechanism. Reference-scoped keys let you override that for the reference side only.

Be sure to:

liquibase.aws.authType: IAM
liquibase.aws.reference.authType: IAM
liquibase.aws.reference.region: your_region

To send the reference connection back to password authentication while the target uses IAM, set the reference selector to DEFAULT. The sentinel is case-insensitive.

liquibase.aws.authType: IAM
liquibase.aws.reference.authType: DEFAULT
liquibase.command.referencePassword: your_password

Liquibase validates each connection separately and names the reference-scoped key when the reference side is misconfigured.

Note: liquibase.aws.reference.roleArn has no opt-out sentinel. Setting it to DEFAULT sends the literal string DEFAULT to STS as a role ARN, and setting it to an empty string inherits the primary value. A reference connection cannot currently opt out of an inherited primary roleArn through configuration. Give the reference connection its own role ARN instead.

4

Test your connection

Create a changelog file in your project directory and add a changeset. Liquibase accepts XML, SQL, YAML, and JSON.

loading

loading

loading

loading

Run update to confirm Liquibase authenticates and reaches your database.

liquibase --changelog-file=changelog.xml update

Liquibase generates an IAM token, connects, and creates the DATABASECHANGELOG and DATABASECHANGELOGLOCK tables. The log records that the password value resolved to an AWS RDS IAM token. The token itself is masked.

Troubleshooting

Set liquibase.aws.authType=IAM to enable RDS IAM authentication

Your password value starts with aws-rds-iam, but liquibase.aws.authType is not set to IAM. Liquibase requires the explicit opt-in so that it never has to guess whether you intended IAM authentication. Add liquibase.aws.authType: IAM to your configuration.

The database password is a static credential rather than an aws-rds-iam reference

You set liquibase.aws.authType to IAM, but the password is a literal value or is empty. Liquibase fails here rather than connecting with a static password, which would not be what the configuration asks for. Either change the password to an aws-rds-iam reference, or unset liquibase.aws.authType if you did not intend to use IAM authentication.

No region could be resolved

Liquibase found no region either inline in the password value or in liquibase.aws.region. Add one of the two. An inline region wins when both are present.

The JDBC URL is missing the required SSL parameter

Liquibase checks for SSL before connecting. For PostgreSQL add sslmode=require or stricter. For MySQL add sslMode=REQUIRED or stricter, or pair useSSL=true with requireSSL=true. This check runs client-side, so it fails whether or not the database is reachable.

The URL declares a mis-cased SSL parameter name

The JDBC driver ignores a parameter whose name is mis-cased, so Liquibase rejects it rather than let the token travel unencrypted. Match the engine exactly. PostgreSQL uses sslmode and MySQL uses sslMode. Parameter values are not case-sensitive, so sslmode=REQUIRE is accepted.

STS AssumeRole failed

Confirm the role ARN is correct and that your source credentials hold sts:AssumeRole permission for it. Confirm the role's trust policy allows your source principal to assume it, and that the role itself carries rds-db:connect on the target database.

This error also appears when the role ARN and its permissions are both correct but Liquibase resolved credentials from a different AWS account than you expected. Liquibase reads credentials through the default AWS provider chain and has no setting of its own for choosing a profile, so it uses your default profile unless the environment names another one. A --profile argument on an AWS CLI command such as aws ssm start-session applies to that command alone and does not carry into the Liquibase run.

Set AWS_PROFILE to the profile you intend Liquibase to use, or export that profile's credentials into your environment before running Liquibase.

Unable to load credentials from any of the providers

The default credential provider chain resolved nothing usable. Confirm your credentials are available to the chain, then check the log for a line naming the profile Liquibase selected.

If you sign in with AWS SSO or IAM Identity Center, confirm your session is current by running aws sso login, then confirm AWS_PROFILE names the profile you intend to use. As a fallback, export the resolved credentials into your environment before running Liquibase.

Be sure to:

  • Replace your_profile with the name of your AWS profile. For example, liquibase-rds-iam

loading

PAM authentication failed, or Access denied

Your AWS credentials resolved and the token generated, but the database rejected the login. Confirm the database user is mapped to IAM. On PostgreSQL the user needs the rds_iam role. On MySQL the user must be created with AWSAuthenticationPlugin. Also confirm the token is fresh, because IAM tokens expire 15 minutes after they are generated.

Cannot find database driver

Liquibase Secure bundles the PostgreSQL and MariaDB drivers, but not MySQL Connector/J. To connect to a MySQL database, add the MySQL Connector/J JAR to the lib directory in your Liquibase installation. A jdbc:mariadb:// URL does not work around this for RDS IAM specifically: the feature only recognizes postgresql and mysql as JDBC schemes and rejects mariadb before generating a token.

Connecting through a bastion host or tunnel

The IAM token is signed for the database endpoint, not for the address you connect to. When you reach the database through a port forward or bastion host, generate the token with the real database endpoint while pointing the JDBC URL at your local address. A token generated for localhost is rejected.