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.
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.
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.
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.
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:
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/*", ] }
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.
{ "Sid": "allow-parameter-store-decryption", "Effect": "Allow", "Action": [ "kms:ListKeys", "kms:ListAliases", "kms:Describe*", "kms:Decrypt" ], "Resource": "project-kms-key-arn" }
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']
Here are some best practices to help you implement the AWS Systems Manager Parameter Store in a secure fashion:
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!
--I work at a staffing agency. Day in and day out, I get to hear our recruiters prep candidates as…
Getting into DevOps is like any other career, in the sense that it is a life-altering decision - and, with…
If you've managed PostgreSQL databases in the past, you know how important it is to have proper monitoring in place…
Not too long ago, I was searching for information on the AWS Solutions Architect Professional certification exam. I was trying…
So you've launched a new application in production, and your applications are performing snappily as you might expect. The cloud…
It's Not Easy Doing Everything There's an oft-circulated image in the technology sector - a company looking for a Swift…