Amazon Web Services offers a way to connect to a MySQL or PostgreSQL database without having a password, instead an authentication token can be used.
Within AWS this type of authentication is called RDS IAM.
Users don’t need to store an username and password and credentials don’t need to be stored in the database, which makes this a secure authentication method.

So, this makes it interesting to use this in your Spring Boot application. Spring Boot will use a HikariCP connection pool by default, but HikariCP 4.0.3 doesn’t support the use of authentication tokens.

So, how do I make this work within my Spring Boot application?

  1. Enable RDS IAM for your database

  2. Create a custom Hikari DataSource

  3. Update application properties

Enable RDS IAM for your database

Enabling RDS IAM for your database can be done on the AWS Console, AWS CLI or by your favourite infrastructure as code solution. When using AWS CDK to enable RDS IAM and granting your service to connect permission, you’ll need the database resource id. Sadly this isn’t exposed by CloudFormation (see GitHub ticket) so, you’ll need a workaround to add the policy to your service. You can find a workaround in this comment on the ticket.

  1. Enable RDS IAM for your database ✓

  2. Create a custom Hikari DataSource

  3. Update application properties

Create a custom Hikari DataSource

The Hikari DataSource doesn’t support authentication token as the datasource expects credentials for the lifetime of the datasource. Meaning you’ll need to restart your service to be able to update the credentials, this isn’t a suitable situation when using RDS IAM. With the creation of a custom Hikari DataSource you can make it support requesting an authentication token.

By overriding the getPassword() method and requesting a token, you’ll get a new token every time the DataSource is requesting a password. Requesting a token needs the database’s hostname and port, which we can extract from the JDBC URL from the DataSource.

public class RdsIamHikariDataSource extends HikariDataSource {

    @Override
    public String getPassword() {
        return getToken();
    }

    private String getToken() {
        var region = new DefaultAwsRegionProviderChain().getRegion();
        var hostnamePort = getHostnamePort();

        RdsIamAuthTokenGenerator generator = RdsIamAuthTokenGenerator.builder()
            .credentials(new DefaultAWSCredentialsProviderChain())
            .region(region)
            .build();

        GetIamAuthTokenRequest request = GetIamAuthTokenRequest.builder()
            .hostname(hostnamePort.getFirst())
            .port(hostnamePort.getSecond())
            .userName(getUsername())
            .build();

        return generator.getAuthToken(request);
    }

    // JDBC URL has a standard URL format, like: jdbc:postgresql://localhost:5432/test_database
    private Pair<String, Integer> getHostnamePort() {
        var slashing = getJdbcUrl().indexOf("//") + 2;
        var sub = getJdbcUrl().substring(slashing, getJdbcUrl().indexOf("/", slashing));
        var splitted = sub.split(":");
        return Pair.of(splitted[0], Integer.parseInt(splitted[1]));
    }
}
  1. Enable RDS IAM for your database ✓

  2. Create a custom Hikari DataSource ✓

  3. Update application properties

Update application properties

To use the custom Hikari DataSource and tweak timeout properties to refresh the token before it is invalidated some application properties need to be changed.

1 In order to connect to a RDS IAM enable database the connection needs to support SSL, for the DataSource you can supply those connection parameters on the url as a query string.
2 The username will be the username you granted the rds_iam database GRANT to.
3 The default RDS IAM authentication token lifetime is 15 minutes, so configure the Hikari DataSource max-lifetime a bit lower to prevent using an invalidad authentication token.
spring.datasource.url=jdbc:postgresql://localhost:5432/test_database?ssl=true,sslMode=verify-full,sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory (1)
spring.datasource.username=rds_iam_role (2)
# Connection max lifetime to 14 minutes as the RDS IAM token is valid for 15 minutes
spring.datasource.hikari.max-lifetime=840000 (3)
  1. Enable RDS IAM for your database ✓

  2. Create a custom Hikari DataSource ✓

  3. Update application properties ✓

All set and done

Now you are able to connect your service to the database with an authentication token, instead of standard username and password credentials.

Two main advantages to this approach are:

  • you never have to cycle your passwords again

  • you don’t have to provide usernames and passwords to users who need to connect to the database directly

All about setting up RDS IAM for your database and how to connect to it can be found in the AWS documentation

shadow-left