AWS Security Blog

Rotate Amazon RDS database credentials automatically with AWS Secrets Manager

August 31, 2021:AWS KMS is replacing the termcustomer master key(CMK) withAWS KMS keyandKMS key.The concept has not changed. To prevent breaking changes, AWS KMS is keeping some variations of this term.More info.


Recently, we launchedAWS Secrets Manager,a service that makes it easier to rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle. You can configure Secrets Manager to rotate secrets automatically, which can help you meet your security and compliance needs. Secrets Manager offers built-in integrations for MySQL, PostgreSQL, and Amazon Aurora on Amazon RDS, and can rotate credentials for these databases natively. You can control access to your secrets by using fine-grainedAWS Identity and Access Management(IAM) policies. To retrieve secrets, employees replace plaintext secrets with a call to Secrets Manager APIs, eliminating the need to hard-code secrets in source code or update configuration files and redeploy code when secrets are rotated.

In this post, I introduce thekey features of Secrets Manager.I then show you how to store a database credential for a MySQL database hosted on Amazon RDS and how your applications can access this secret. Finally, I show you how to configure Secrets Manager to rotate this secret automatically.

Key features of Secrets Manager

These features include the ability to:

  • Rotate secrets safely.You can configure Secrets Manager to rotate secrets automatically without disrupting your applications. Secrets Manager offers built-in integrations for rotating credentials forAmazon RDSdatabases for MySQL, PostgreSQL, and Amazon Aurora. You can extend Secrets Manager to meet your custom rotation requirements by creating anAWS Lambdafunction to rotate other types of secrets. For example, you can create an AWS Lambda function to rotate OAuth tokens used in a mobile application. Users and applications retrieve the secret from Secrets Manager, eliminating the need to email secrets to developers or update and redeploy applications after AWS Secrets Manager rotates a secret.
  • Secure and manage secrets centrally.You can store, view, and manage all your secrets. By default, Secrets Manager encrypts these secrets with encryption keys that you own and control. Using fine-grained IAM policies, you can control access to secrets. For example, you can require developers to provide a second factor of authentication when they attempt to retrieve a production database credential. You can also tag secrets to help you discover, organize, and control access to secrets used throughout your organization.
  • Monitor and audit easily.Secrets Manager integrates with AWS logging and monitoring services to enable you to meet your security and compliance requirements. For example, you can auditAWS CloudTraillogs to see when Secrets Manager rotated a secret or configureAWS CloudWatchEvents to alert you when an administrator deletes a secret.
  • Pay as you go.Pay for the secrets you store in Secrets Manager and for the use of these secrets; there are no long-term contracts or licensing fees.

Get started with Secrets Manager

Now that you’re familiar with the key features, I’ll show you how to store the credential for a MySQL database hosted on Amazon RDS. To demonstrate how to retrieve and use the secret, I use a Python application running on Amazon EC2 that requires this database credential to access the MySQL instance. Finally, I show how to configure Secrets Manager to rotate this database credential automatically. Let’s get started.

Phase 1: Store a secret in Secrets Manager

  1. Open theSecrets Manager consoleand selectStore a new secret.

    Secrets Manager console interface
  2. I selectCredentials for RDS databasebecause I’m storing credentials for a MySQL database hosted on Amazon RDS. For this example, I store the credentials for the databasesuperuser.I start by securing thesuperuserbecause it’s the most powerful database credential and has full access over the database.

    Store a new secret interface with Credentials for RDS database selected

    Note:For this example, you need permissions to store secrets in Secrets Manager. To grant these permissions, you can use theAWSSecretsManagerReadWriteAccessmanaged policy.Read the AWS Secrets Manager Documentation for more information aboutthe minimum IAM permissions required to store a secret.

  3. Next, I review the encryption setting and choose to use the default encryption settings. Secrets Manager will encrypt this secret using the Secrets ManagerDefaultEncryptionKeyDefaultEncryptionKey in this account. Alternatively, I can choose to encrypt using a KMS key that I have stored in AWS KMS.

    Select the encryption key interface
  4. Next, I view the list of Amazon RDS instances in my account and select the database this credential accesses. For this example, I select the DB instancemysql-rds-database,and then I selectNext.

    Select the RDS database interface
  5. In this step, I specify values forSecret NameandDescription.For this example, I useApplications/MyApp/MySQL-RDS-Databaseas the name and enter a description of this secret, and then selectNext.

    Secret Name and description interface
  6. For the next step, I keep the default settingDisable automatic rotationbecause my secret is used by my application running on Amazon EC2. I’ll enable rotation after I’ve updated my application (see Phase 2 below) to use Secrets Manager APIs to retrieve secrets. I then selectNext.

    Note:If you’re storing a secret that you’re not using in your application, selectEnable automatic rotation.See ourAWS Secrets Manager getting started guide on rotationfor details.


    Configure automatic rotation interface

  7. Review the information on the next screen and, if everything looks correct, selectStore.We’ve now successfully stored a secret in Secrets Manager.
  8. Next, I selectSee sample code.

    The See sample code button
  9. Take note of the code samples provided. I will use this code to update my application to retrieve the secret using Secrets Manager APIs.

    Python sample code

Phase 2: Update an application to retrieve secret from Secrets Manager

Now that I have stored the secret in Secrets Manager, I update my application to retrieve the database credential from Secrets Manager instead of hard coding this information in a configuration file or source code. For this example, I show how to configure a Python application to retrieve this secret from Secrets Manager.

  1. Iconnect to my Amazon EC2 instance via Secure Shell(SSH).
  2. Previously, I configured my application to retrieve the database user name and password from the configuration file. Below is the source code for my application.
    import MySQLdb
    import config

    def no_secrets_manager_sample()

    # Get the user name, password, and database connection information from a config file.
    database = config.database
    user_name = config.user_name
    password = config.password

    # Use the user name, password, and database connection information to connect to the database
    db = MySQLdb.connect(database.endpoint, user_name, password, database.db_name, database.port)

  3. I use the sample code from Phase 1 above and update my application to retrieve the user name and password from Secrets Manager. This code sets up the client and retrieves and decrypts the secretApplications/MyApp/MySQL-RDS-Database.I’ve added comments to the code to make the code easier to understand.
    # Use the code snippet provided by Secrets Manager.
    import boto3
    from botocore.exceptions import ClientError

    def get_secret():
    #Define the secret you want to retrieve
    secret_name = "Applications/MyApp/MySQL-RDS-Database"
    #Define the Secrets mManager end-point your code should use.
    endpoint_url = "https://secretsmanager.us-east-1.amazonaws"
    region_name = "us-east-1"

    #Setup the client
    session = boto3.session.Session()
    client = session.client(
    service_name='secretsmanager',
    region_name=region_name,
    endpoint_url=endpoint_url
    )

    #Use the client to retrieve the secret
    try:
    get_secret_value_response = client.get_secret_value(
    SecretId=secret_name
    )
    #Error handling to make it easier for your code to tolerate faults
    except ClientError as e:
    if e.response['Error']['Code'] == 'ResourceNotFoundException':
    print( "The requested secret" + secret_name + "was not found" )
    elif e.response['Error']['Code'] == 'InvalidRequestException':
    print( "The request was invalid due to:", e)
    elif e.response['Error']['Code'] == 'InvalidParameterException':
    print( "The request had invalid params:", e)
    else:
    # Decrypted secret using the associated KMS key
    # Depending on whether the secret was a string or binary, one of these fields will be populated
    if 'SecretString' in get_secret_value_response:
    secret = get_secret_value_response['SecretString']
    else:
    binary_secret_data = get_secret_value_response['SecretBinary']

    # Your code goes here.

  4. Applications require permissions to access Secrets Manager. My application runs on Amazon EC2 and uses an IAM role to obtain access to AWS services. I will attach the following policy to my IAM role. This policy uses theGetSecretValueaction to grant my application permissions to read secret from Secrets Manager. This policy also uses the resource element to limit my application to read only theApplications/MyApp/MySQL-RDS-Databasesecret from Secrets Manager. You can visit the AWS Secrets Manager Documentation to understand theminimum IAM permissions required to retrieve a secret.
    {
    "Version": "2012-10-17",
    "Statement": {
    "Sid": "RetrieveDbCredentialFromSecretsManager",
    "Effect": "Allow",
    "Action": "secretsmanager:GetSecretValue",
    "Resource": "arn:aws:secretsmanager:::secret:Applications/MyApp/MySQL-RDS-Database"
    }
    }

Phase 3: Enable Rotation for Your Secret

Rotating secrets periodically is a security best practice because it reduces the risk of misuse of secrets. Secrets Manager makes it easy to follow this security best practice and offers built-in integrations for rotating credentials for MySQL, PostgreSQL, and Amazon Aurora databases hosted on Amazon RDS. When you enable rotation, Secrets Manager creates a Lambda function and attaches an IAM role to this function to execute rotations on a schedule you define.

Note:Configuring rotation is a privileged action that requires several IAM permissions and you should only grant this access to trusted individuals. To grant these permissions, you can use theAWSIAMFullAccessmanaged policy.

Next, I show you how to configure Secrets Manager to rotate the secretApplications/MyApp/MySQL-RDS-Databaseautomatically.

  1. From theSecrets Manager console,I go to the list of secrets and choose the secret I created in the first stepApplications/MyApp/MySQL-RDS-Database.

    List of secrets in the Secrets Manager console
  2. I scroll to Rotation configuration, and then selectEdit rotation.

    Rotation configuration interface
  3. To enable rotation, I selectEnable automatic rotation.I then choose how frequently I want Secrets Manager to rotate this secret. For this example, I set the rotation interval to 60 days.

    Edit rotation configuration interface
  4. Next, Secrets Manager requires permissions to rotate this secret on your behalf. Because I’m storing thesuperuserdatabase credential, Secrets Manager can use this credential to perform rotations. Therefore, I selectUse the secret that I provided in step 1,and then selectNext.

    Select which secret to use in the Edit rotation configuration interface
  5. The banner on the next screen confirms that I have successfully configured rotation and the first rotation is in progress, which enables you to verify that rotation is functioning as expected. Secrets Manager will rotate this credential automatically every 60 days.

    Confirmation banner message

Summary

I introduced AWS Secrets Manager, explained the key benefits, and showed you how to help meet your compliance requirements by configuring AWS Secrets Manager to rotate database credentials automatically on your behalf. Secrets Manager helps you protect access to your applications, services, and IT resources without the upfront investment and on-going maintenance costs of operating your own secrets management infrastructure. To get started, visit theSecrets Manager console.To learn more, visitSecrets Manager documentation.

If you have comments about this post, submit them in theCommentssection below. If you have questions about anything in this post, start a new thread on theSecrets Manager forum.

Want more AWS Security news? Follow us onTwitter.