Implementing AWS Parameter Store

Your Cloud and Infrastructure-as-Code Expert.

Implementing AWS Parameter Store

AWS Systems Manager Parameter Store

AWS Systems Manager Parameter Store

In today’s technology, application security is receiving much more attention than ever before. With the multitude of data breaches and hacks occurring across the internet, it’s evident that securing our application credentials in an encrypted fashion is a must.

In this article, I’d like to talk about the Systems Manager Parameter Store, and how we can leverage it to securely access and manage our application credentials. I’ll also be highlighting why leveraging the Parameter Store is preferred over using environment variables or some other methods.

At the tail end of the article, we’ll go over a code example that leverages Python and the Boto3 module to retrieve a parameter from the Parameter Store.

Environment Variable Pitfalls

It’s also clear that leveraging environment variables just isn’t a preferred way of providing sensitive application secrets into our processes anymore.

Whether the environment variables are being passed through to a process explicitly, or at a global level, there’s always the possibility that an intruder can exfiltrate your credentials. On Linux, a user could simply track down the process of your application’s process and use a command like the following to view the environment variables the app is using:

cat /proc/pid/environ

For globally defined variables, a simple env command will spill all of our precious credentials right out to the console.

Environment variables can be used for less sensitive things, but we should absolutely store usernames, passwords and secure tokens somewhere else.

Credentials in Files, Containers, AMIs – Oh My!

AWS Parameter Store Security

In most cases, anyone who can take a look at our credentials file can employ any of the permissions that those credentials enable the application to.

Baking credentials into AMIs or Docker containers isn’t necessarily a secure approach either because then it opens up the possibility for an intruder or another employee to locate the credentials on disk and exploit them.

Depending on how credentials are provided to a container, an attacker could restart a stopped container and figure out a way to exfiltrate the credentials from the container. Maybe the file permissions weren’t set as secure as we should have made them, or maybe we’re running an outdated version of a package that makes us vulnerable. There are so many attack vectors out there, so we should be diligent in our efforts to keep credentials off the disk.

Really what we want to do is to only store credentials in memory during the container’s lifecycle, and have them disappear when the container stops.

AWS Systems Manager Parameter Store

The Parameter Store is a service that allows one to create a hierarchy of secure credentials in a vault. We can choose to encrypt parameters using KMS keys or to store them in plain-text if we choose. In our code base, we can leverage the Parameter Store API to make requests path-based requests to retrieve the value of our credentials.

Parameter Hierarchy Example – Email-worker Service

It’s best to segment our application’s parameters using a consistent naming convention. Take some time to think about how you want to lay your hierarchy out. Consider breaking some of your default values out into an environment-agnostic path (as seen in ‘/defaults/’ below).

One can set an environment variable in each application called ENVIRONMENT, which can be used to concatenate the parameter path during runtime. One might set this in their ECS task definition or Ansible playbook, depending on how the system is provisioned.

Here are some examples of what this might look like:

  • email-worker/${env.ENVIRONMENT}/db/username
  • email-worker/${env.ENVIRONMENT}/db/password
  • email-worker/defaults/polling-interval

Authenticated Access to Parameters

In order for our application to load parameters, our IAM role, task role, etc. will need to be able to perform ssm:GetParameters on the appropriate parameters you choose.

Here’s an example IAM policy that gives you an idea of how we could grant a service called email-worker access to the staging environment’s unencrypted parameters. We’ll cover a little further below.

{
  "Sid": "",
  "Effect": "Allow",
  "Action": "ssm:GetParameters",
  "Resource": [
    "arn:aws:ssm:*:*:parameter/email-worker/staging/*",
  ]
}

Retrieving Encrypted Secrets

Parameters stored in the Parameter Store are encrypted using KMS keys. Given that, some of the same restrictions of KMS apply. The length of the secure string cannot exceed 4096 characters.

In order for our application to be able to decrypt encrypted parameters, they’ll need to have the following permissions. I definitely recommend using a non-default KMS encryption key; a separate key for each project/environment would do nicely.

IAM Policy Snippet for KMS:

{
  "Sid": "allow-parameter-store-decryption",
  "Effect": "Allow",
  "Action": [
     "kms:ListKeys",
     "kms:ListAliases",
     "kms:Describe*",
     "kms:Decrypt"
  ],
  "Resource": "project-kms-key-arn"
}

Code Example to Retrieve a Parameter

For those of you that use Python, here’s an example snippet that illustrates how easy one can retrieve an encrypted variable from the Parameter Store using the Boto3 module:

import os
environment = os.environ['ENVIRONMENT']
ssm = boto3.client('ssm',
   region_name='us-east-1'
)

# Retrieve encrypted parameter
parameter_name = 'email-worker/%s/db/username' % environment
response = ssm.get_parameters(
   Names=[
      parameter_name,
   ],
   WithDecryption=True
)
db_user = response['Parameters'][0]['Value']

Recommended Best Practices

Here are some best practices to help you implement the AWS Systems Manager Parameter Store in a secure fashion:

  • Don’t use the default KMS key for encrypting secrets
  • Consider creating a separate KMS key for each project/environment (i.e.: website-staging)
  • Take your time planning out a standardized parameter hierarchy, and stay consistent
  • Implement the least privilege principle to compartmentalize access to secure credentials
  • Carefully create your KMS keys and ensure only authorized users have access to them
  • Configure your KMS keys to be rotated, via IAM service

I hope you’ve found this article on monitoring your applications informative, and I’d like to invite you to check out our product, Clouductivity Navigator – a Chrome Extension to improve your productivity in AWS. It helps you get to the documentation and AWS service pages you need, without clicking through the console. Download your free trial today!

--

Clouductivity - Marcus Bastian About the Author

Marcus Bastian is a Senior Site Reliability Engineer that works with AWS and Google Cloud customers to implement, automate, and improve the performance of their applications.

Find his LinkedIn here.

Clouductivity - AWS Solutions Architect Professional Certification - Marcus Bastian