Simple Secrets Management via AWS’ EC2 Parameter Store
Amazon’s EC2 Systems Manager was launched at re:Invent 2016. It brings with it a lot of very useful tools meant to ease the administration and management of your EC2 instances and associated resources. One part of the EC2 Systems Manager suite is the Parameter Store. I think the Parameter Store is actually really quite powerful and can help secure your AWS environment in ways that may not be initially obvious.
The Parameter Store offers the ability to store 3 different types of data, which can then be programmatically accessed via the SSM API. The 3 types of data are: String, String List, and Secure String. In this post, I want to concentrate on the “Secure String” option and how it can be used to store and retrieve secrets within your AWS environment.
Documentation from AWS on the Parameter Store can be found here: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/systems-manager-paramstore.html
How are secure strings stored?
When you store a secure string in the EC2 Parameter Store, the data is encrypted via a KMS key associated with your account. You can either choose the default KMS key, or create your own. By using KMS, we can easily secure these strings of data within the AWS ecosystem, utilizing all of the benefits KMS gives. For more information on KMS, visit AWS’ KMS Product Overview.
Let’s go through a quick example of creating our own KMS key which we can later use with the EC2 Parameter Store:
- Navigate to KMS within the AWS Console (Services > IAM > Encryption Keys).
- Click “Create Key”.
- You’ll be prompted to enter the following information:
- Alias: a friendly key name
- Description: a detailed description of the key
- Advanced Options: either leave it as KMS to let AWS generate a key for you, or choose “External” to upload your own key.
- Click Next Step.
- On the next page, define who can Administer this key. These will be IAM users who can grant/remove permissions to use the key, as well as potentially delete the key. Click Next Step.
- Next, define who can actually use this key. This is where you can grant access to individuals or roles who can use the key to decrypt secrets. Click Next Step.
- These can be changed later, of course.
- This is where you can grant an EC2 role access to be able to decrypt secrets.
- Next, you will be presented with the Key’s policy. Click Finish.
- The key is now shown in the list of available KMS keys on your account. You can click on the key to view its settings and change users or roles who have access to use the key.
Storing a Secure String
There are 2 main ways to add a secure string to the EC2 Systems Manager for retrieval. Keys can be added via the console, under the EC2 section, or they can be created programmatically via API/SDK/CLI.
2018–09–30 Update: Previously, I mentioned that you cannot choose which KMS key to use when creating a secure sting in the console. That has since changed and you can now select a custom KMS key to use for encrypting secure strings directly within the AWS console!
The AWS CLI SSM reference can be found here: http://docs.aws.amazon.com/cli/latest/reference/ssm/
To add a secure string via the AWS CLI, use the ssm put-parameter command:
Using our example KMS key, we can create store data in the following way:
After executing the above command, the secure string is available for use. It can be verified by viewing the EC2 Parameter Store in the console.
A note about Secure String values
A value can be whatever you want it to be — it can be a simple string or password, or it can be something more detailed, like a JSON string. By using a JSON string, you can programmatically access that data and parse the string into a JSON object. This is useful for storing perhaps an IAM Access Key and Secret Access Key:
Accessing Values via CLI
Via the CLI, you can access secure strings using the ssm get-parameters command:
Using our previous example:
Note the “with-decryption” option — this specifies to return the decrypted string. The user or role who runs this command should have access to use the KMS key in order to successfully execute this command.
This command can be stored into a variable in a bash script, and then passed into other commands which need the secret string. For example, setting up an application configuration with a database password, the password can be pulled each time an application is configured, rather than storing it in plain text on S3 or somewhere else.
Accessing Values via Python SDK
The official AWS SDKs allow you to access EC2 Parameters. Below is a Python Boto3 example.
Note that the IAM user or role which executes this Python script needs access to use the KMS key which has encrypted this string.
This can of course be executed within any application which has access to the AWS SDK, whether it uses any other AWS services or not. This gives a great amount of flexibility for storing and pulling down secrets directly at an application’s runtime, rather than having to store a secure string directly within an application script, or pull it from somewhere less secure.
There are, of course, many other use cases for this functionality. There are also plenty of other more full-featured secrets storage and management platforms available, but I believe that the EC2 Systems Manager Parameter Store provides a very easy, minimalist, way to securely store and access secrets directly within AWS and managed via IAM permissions.