What Every Developer Should Know About AWS Vault
I came across AWS Vault when I first started my cloud journey. At the time, I used the AWS Command Line Interface (AWS CLI) and I didn’t understand why this tool existed. I was able to access AWS services with the AWS CLI by adding my credentials. So, what’s the problem?
AWS Vault solves problems such as vulnerable plaintext credentials and cumbersome token refreshing. Juggling many AWS accounts and securing local credentialing has never been easier. AWS Vault is an essential tool for AWS CLI users, cloud developers, and those using many accounts. To learn more about how this works and how it can optimize your cloud practices, keep reading!
What Problem Does AWS Vault Solve?
The primary problem addressed by AWS Vault is that it allows you to avoid using plaintext credentials in commonly known folders (
.aws). This will reduce the risk of unauthorized access and compromised credentials. Plaintext credentials are easily accessible and pose security and financial risks if compromised. AWS Vault prevents these risks and protects against user errors. The accidental exposure of credentials or compromised machines will limit the risk of your account.
[email protected]:$ aws configure AWS Access Key ID: ABCDEFGHJKLMNOP AWS Secret Access Key: 12345678910293 Default region name: us-east-2 Default output format: json AWS Configured!
[default] aws_access_key_id=ABCDEFGHJKLMNOP aws_secret_access_key=12345678910293
Figures 1 and 2 illustrate our problem. If you are reading this article, you have likely completed the steps in Figure 1. This is the typical workflow for setting up AWS credentials for the first time. Figure 2 shows how these credentials are stored by default. Every cloud developer who follows the default path for managing AWS credentials is left potentially exposed by default.
Seasoned AWS developers are familiar with the AWS Security Token Service (AWS STS). This service allows users to retrieve short-lived tokens. You can then use these tokens to access cloud resources. They can be used in the AWS CLI or by the AWS Software Development Kit (AWS SDK). If credentials are leaked, they would only be valid for a small amount of time. However, it can be cumbersome to regularly refresh a token.
Managing more than one AWS account is another pain point. The AWS CLI does a great job of handling profiles. Of course, this can still be nerve-wracking when simultaneously using more than one account. It also still leaves plaintext credentials exposed. There has to be a better way!
AWS Single Sign-On (AWS SSO) (or its successor AWS IAM Identity Center) is a great solution for managing multiple profiles locally. AWS SSO users are required to log in using a browser to get a short-lived token. This is the best solution since it also supports MFA and roles. Plaintext credentials do not get exposed! This solves most of the same problems as AWS Vault. Sadly, this can be tedious to configure. It requires in-depth knowledge of AWS services and permissions.
Lastly, the challenge of local development credentialing for enterprise-level applications can be particularly difficult. When deploying to the cloud, it is easy to assign roles to resources and delegate permissions. However, developers may need access to cloud resources or services locally. Finding consistent patterns for teams to locally access cloud resources securely can be a challenge.
How Does AWS Vault Solve These Problems?
AWS Vault offers various options for effortlessly storing encrypted credentials. This includes Windows, MacOS, or Linux credential managers, secret services, and encrypted files. Access and secret keys get stored securely in their respective OS storage units. Credentials are never exposed in a shell session history.
# Store AWS credentials for the "jonsmith" profile $ aws-vault add jonsmith Enter Access Key Id: ABDCDEFDASDASF Enter Secret Key: %%% # Execute a command (using temporary credentials) $ aws-vault exec jonsmith -- aws s3 ls bucket_1 bucket_2 ## equivalent using aws profiles aws s3 ls --profile jonsmith
Figure 3 demonstrates how easy it is to store encrypted credentials using
aws-vault add. You can then execute a command by using
aws-vault exec. This is followed by your profile name and the AWS CLI command you want to run. With AWS Vault, you specify the profile first. In contrast, AWS profiles typically add the profile last. Specifying the profile first, personally, gives me more peace of mind.
Figure 4 shows the AWS Vault workflow. A user adds their credentials using
aws-vault add. They are encrypted and either stored in the OS credential manager or on disk.
aws-vault exec creates a session using the encrypted credentials. AWS STS obtains temporary credentials and stores them in a scoped shell session. You can then use standard AWS environmental variables in your session. This streamlined approach to credential management simplifies the development process. It also ensures continuous access to your cloud resources.
$ aws-vault exec jonsmith -- env | grep AWS AWS_VAULT=jonsmith AWS_DEFAULT_REGION=us-east-1 AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=%%% AWS_SECRET_ACCESS_KEY=%%% AWS_SESSION_TOKEN=%%% AWS_CREDENTIAL_EXPIRATION=2020-04-16T11:16:27Z
Figure 5 shows the environment variables available when creating a session. An automatic token refreshing mechanism minimizes the need for manually updating tokens or environment variables. This ensures uninterrupted access to cloud resources. Also, AWS Vault supports roles and Multi-Factor Authentication (MFA). This provides an extra layer of security for your AWS credentials.
Once the token expires, the system invalidates the session. You either need to add handling to reload the token or you can use an AWS Vault metadata server feature.
$ aws-vault exec --server jonsmith -- env | grep AWS AWS_VAULT=jonsmith AWS_DEFAULT_REGION=us-east-1 AWS_REGION=us-east-1 AWS_CONTAINER_CREDENTIALS_FULL_URI=%%% AWS_CONTAINER_AUTHORIZATION_TOKEN=%%%
--server to the
exec command you can make use of the container credential provider. This is very useful for long-running tasks. The provider was built for the AWS Elastic Container Service. It allows anything that uses the AWS SDK to automatically refresh credentials as needed. Session times can be as short as possible! Figure 6 shows how the environment variables change when using this option.
AWS Vault allows you to securely manage multiple AWS accounts and profiles. By using Vault, you can easily switch between profiles. You simply need to specify the name of the profile while running
exec. This makes managing multiple AWS accounts much easier and more secure. You do not risk exposing plaintext credentials!
Under the Hood
AWS Vault is brought to you by 99Designs. You still can read their original AWS Vault announcement blog post from 2015. It’s a great read about the state of the cloud at the time and explains their motivation for creating AWS Vault.
Their GitHub does a good job of covering different ways to use the product. The project is written in Go language and uses a nifty package named Kingpin for interfacing with a CLI. They also developed a proprietary library named Keyring. This is a common interface to a range of secure credential storage services.
They were inspired by a few cool projects you can still find on GitHub. Here are some references to the no longer maintained project: aws-keychain (improved upon their design), awssudo (used their rotation idea for updating their sessions), and hologram (exposes metadata). It seems as though they took the best parts of these apps and made something really special!
Most software engineers can work remotely. Using Microsoft Remote Desktop Protocol (RDP) clients can have issues such as preferences between switching operating systems (OS) or visual lag. Using Secure Shell (SSH) can be a more pleasant option. VS Code has a great guide on setting up SSH. This allows you to write code on your local machine while keeping your code on your work machine. This results in a smooth and efficient developer experience.
This is a common setup for developers. However, in my experience, AWS Vault has limitations when working over SSH, specifically on Windows OS. Windows Credential Manager has restricted access over SSH. This can be a roadblock for developers working remotely.
# Store AWS credentials for the "jonsmith" profile on disk (encrypted) $ aws-vault add jonsmith --backend=file Enter Access Key Id: ABDCDEFDASDASF Enter Secret Key: %%% Enter passphrase to unlock "~/.awsvault/keys/": ## load encryted credentials from disk $ aws-vault exec jonsmith --backend=file -- aws s3 ls Enter passphrase to unlock "~/.awsvault/keys/": bucket_1 bucket_2
AWS Vault has you covered! Figure 7 demonstrates using the
--backend=file option. This allows you to store a salt-encrypted secret on disk. You can access these credentials both locally and over SSH. This is not the most ideal situation and storing credentials on disk should be avoided. However, this is a good alternative to storing plaintext credentials.
$ aws-vault exec jonsmith -- aws s3 ls bucket_1 bucket_2 $ aws-vault exec jonsmith # All subsequent commands will use jonsmith's credentials
All the examples so far have used the
-- feature. This allows you to load credentials and run an AWS command in one line. However, there is a nifty trick to pin your credentials to a session. This is a less verbose way of running multiple commands against the same account. _Figure 8 _shows that you simply need to omit
--. This will create an interactive terminal and any subsequent commands will have access to the specified credentials.
AWS Vault is a powerful tool that simplifies the management of AWS credentials for developers and cloud engineers. It solves the problem of plaintext credential exposure and cumbersome token refreshing. You can store encrypted credentials securely and easily switch between profiles. It has allowed me and my teams to remove plaintext AWS credentials from our machines altogether. Overall, AWS Vault streamlines the development process, improves security, and ensures compliance with security standards. It is a vault-uable addition to any cloud engineer’s toolkit. 😆