AWS Secrets Manager makes working with access keys (like database credentials) easier by storing them remotely and controlling the access of them behind IAM permissions. This allows you to smoothly rotate access keys and fetch the latest one whenever needed.
What Does Secrets Manager Do?
Here’s an example. Say you’re creating a build script for your servers that will automate your installation process, usually to make use of Auto Scaling and automated deployment. You need to connect WordPress to an external MySQL server.
The simplest solution would be to store the MySQL password in plaintext as part of the build script. This obviously isn’t security best practice, and doesn’t scale well beyond a single instance operated by a single employee. Additionally, if you’re separating your dev and prod environments, this secret needs to be updated for each environment, which is a hassle.
The better solution is Secrets Manager. Instead of storing the MySQL password in plaintext, you store it in Secrets Manager, and when you need to use it, you perform an API call to Secrets Manager, which returns the secret. This allows you to secure access to your secrets using IAM roles and permissions, which is a much better system, and one that you’re already using if your company is on AWS.
Also, because Secrets Manager acts as a single authoritative data store, it makes rotation of secrets much more easy, which is an important part of ongoing security.
Just to be clear—Secrets Manager doesn’t automatically make handling important secrets trivial. At the end of the day, you’re still requesting sensitive information that’s going to be stored on disk or in memory on your server. Anyone that can access the server will still be able to access the secret, and you’ll need to have good IAM permissions policies in place to lock down access. However, without Secrets Manager, you wouldn’t be able to control this access at all using IAM, and would potentially have important keys stored in other places, such as easily accessible Git repos.
Secrets Manager can be used to store any kind of key, including JSON. However, it’s commonly used to store database credentials, and as such has built in integration for RDS that can automatically configure and rotate credentials for you.
How to Use Secrets Manager
Head over to the Secrets Manager console, and click “Store A New Secret.”
If you’re setting up a secret to store credentials for RDS, or any of AWS’s other DB services, you can select that as the type, enter in the username and password, and select the database that you want to use with this secret.
If you’re storing anything else, you’ll want to select “Other Type Of Secret.” If you’re storing a series of key-value pairs, you can enter them in here, but if you have a more complex JSON schema, you can enter in the entire thing as plaintext under the “Plaintext” tab.
Click “Next,” give it a name, and any tags you might want to add for organizational purposes.
On the next screen, you have the option of configuring automatic rotation. This will call a Lambda function of your choosing every month or so, and rotate the key for a new value. You’ll probably want to set up your Lambda function to flush the caches of your client applications, so they all must fetch the new secret.
Click “Next,” and click “Store” to create the secret.
Accessing the secret is pretty easy. Provided you have the AWS CLI installed and configured with a user or role that has permission to fetch the secret, you can access it using
secretsmanager get-secrete-value. This returns JSON output, so you’ll likely want to pipe it to
jq for processing.
aws secretsmanager get-secret-value --secret-id Confidential_Info | jq
This returns some metadata about your string as well as the string itself in the
SecretString parameter. It’s encoded in a single string, but you can use
fromjson directive to return the actual JSON value of the string.
| jq '.SecretString | fromjson'
If you’re retrieving secrets very often (at runtime), you’ll want to make use of a client-side cache so you’re not sending thousands of API requests every second. AWS provides a few client-side libraries for working with Secrets Manager, but you can always implement it yourself in the language of your choice.
If you want to automate the creation of secrets, you can do so with
aws secretsmanager create-secret --name <value> --secret-string <value>
Configuring IAM Access
You’ll want to set up custom IAM policies to grant read access to individual secrets based on the Amazon Resource Name (ARN). From the IAM Management Console, create a new role (or edit your EC2 instance’s existing one), and add “Read” access for Secrets Manager.
Below, you’ll want to add an ARN to restrict access. Enter in the Secret ID, and click “Add.”
Create the new policy, attach the role to your EC2 instance if necessary, and test to verify that you can access only the secret assigned to the policy.