AWS Vault is a tool to securely store and access AWS credentials in a development environment.
AWS Vault stores IAM credentials in your operating system’s secure keystore and then generates temporary credentials from those to expose to your shell and applications. It’s designed to be complementary to the AWS CLI tools, and is aware of your profiles and configuration in ~/.aws/config
.
https://github.com/99designs/aws-vault
Typical Authentication Flow
When you configure your IAM user using the AWS CLI, it stores your credentials in plain text on your machine by default in an .aws directory on your home directory. This is common knowledge and can be exploited in cases where your computer gets compromised and all of this can happen without your knowledge. With your credentials, an attacker can use them to do almost anything in your AWS account based on the permissions set on the associated IAM user.
Pros:
- Simple to configure for a single AWS Account
- Authentication to AWS can be entirely transparent to the end-user
Cons:
- Long-term credentials are stored on the local disk of your laptop in plain-text, which can lead to credential leakage and present a security risk
- Complex to configure when you are Well-Architected and have more than one AWS Account
AWS Vault securely stores and access AWS credentials in our local setup using our operating system’s secure keystore. It then generates temporary credentials from the keystore and exposes it to our shell and applications, making sure we do not store these credentials in plain text.
Quick start
# Setup a New Profile
# 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
# open a browser window and login to the AWS Console
$ aws-vault login jonsmith
# List credentials
$ aws-vault list
Profile Credentials Sessions
======= =========== ========
jonsmith jonsmith -
Environment variables
To configure the default flag values of aws-vault
and its subcommands:
AWS_VAULT_BACKEND:
Secret backend to use (see the flag--backend
)AWS_VAULT_KEYCHAIN_NAME:
Name of macOS keychain to use (see the flag--keychain
)AWS_VAULT_PROMPT:
Prompt driver to use (see the flag--prompt
)AWS_VAULT_PASS_PASSWORD_STORE_DIR:
Pass password store directory (see the flag--pass-dir
)AWS_VAULT_PASS_CMD:
Name of the pass executable (see the flag--pass-cmd
)AWS_VAULT_PASS_PREFIX:
Prefix to prepend to the item path stored in pass (see the flag--pass-prefix
)AWS_VAULT_FILE_DIR:
Directory for the “file” password store (see the flag--file-dir
)AWS_VAULT_FILE_PASSPHRASE:
Password for the “file” password storeAWS_CONFIG_FILE:
The location of the AWS config file
To override the AWS config file (used in the exec
, login
and rotate
subcommands):
AWS_REGION:
The AWS regionAWS_DEFAULT_REGION:
The AWS region, applied only ifAWS_REGION
isn’t setAWS_STS_REGIONAL_ENDPOINTS:
STS endpoint resolution logic, must be “regional” or “legacy”AWS_MFA_SERIAL:
The identification number of the MFA device to useAWS_ROLE_ARN:
Specifies the ARN of an IAM role in the active profileAWS_ROLE_SESSION_NAME:
Specifies the name to attach to the role session in the active profile
To override session durations (used in exec
and login
):
AWS_SESSION_TOKEN_TTL:
Expiration time for theGetSessionToken
credentials. Defaults to 1hAWS_CHAINED_SESSION_TOKEN_TTL:
Expiration time for theGetSessionToken
credentials when chaining profiles. Defaults to 8hAWS_ASSUME_ROLE_TTL:
Expiration time for theAssumeRole
credentials. Defaults to 1hAWS_FEDERATION_TOKEN_TTL:
Expiration time for theGetFederationToken
credentials. Defaults to 1hAWS_MIN_TTL:
The minimum expiration time allowed for a credential. Defaults to 5m
Note: that the session durations above expect a unit after the number (e.g. 12h or 43200s).
To override or set session tagging (used in exec
):
AWS_SESSION_TAGS:
Comma separated key-value list of tags passed with theAssumeRole
call, overridessession_tags
profile config variableAWS_TRANSITIVE_TAGS:
Comma separated list of transitive tags passed with theAssumeRole
call, overridestransitive_session_tags
profile config variable
To override or set the source identity (used in exec
and login
):
AWS_SOURCE_IDENTITY:
Specifies the source identity for assumed role sessions
Backends
You can choose among different pluggable secret storage backends. You can set the backend using the --backend
flag or the AWS_VAULT_BACKEND
environment variable. Run aws-vault --help
to see what your --backend
flag supports.
The supported vaulting backends are:
- macOS Keychain
- Windows Credential Manager
- Secret Service (Gnome Keyring, KWallet)
- KWallet
- Pass
- Encrypted file
Managing credentials
Using multiple profiles
In addition to using IAM roles to assume temporary privileges as described in README.md, aws-vault can also be used with multiple profiles directly. This allows you to use multiple separate AWS accounts that have no relation to one another, such as work and home.
# Store AWS credentials for the "home" profile
$ aws-vault add home
Enter Access Key Id: ABDCDEFDASDASF
Enter Secret Key: %
# Execute a command using temporary credentials
$ aws-vault exec home -- aws s3 ls
bucket_1
bucket_2
# store credentials for the "work" profile
$ aws-vault add work
Enter Access Key Id: ABDCDEFDASDASF
Enter Secret Key: %
# Execute a command using temporary credentials
$ aws-vault exec work -- aws s3 ls
another_bucket
Here is an example ~/.aws/config
file, to help show the configuration. It defines two AWS accounts: “home” and “work”, both of which use MFA. The work account provides two roles, allowing the user to become either profile.
[default]
region = us-east-1
[profile home]
mfa_serial = arn:aws:iam::111111111111:mfa/home-account
[profile work]
mfa_serial = arn:aws:iam::111111111111:mfa/work-account
role_arn = arn:aws:iam::111111111111:role/ReadOnly
[profile work-admin]
role_arn = arn:aws:iam::111111111111:role/Administrator
source_profile = work
Listing profiles and credentials
You can use the aws-vault list
command to list out the defined profiles, and any session associated with them.
$ aws-vault list
Profile Credentials Sessions
======= =========== ========
home home
work work 1525456570
work-read-only work
work-admin work
Removing credentials
The aws-vault remove
command can be used to remove credentials. It works similarly to the aws-vault add command.
# Remove AWS credentials for the "work" profile
$ aws-vault remove work
Delete credentials for profile "work"? (y|N) y
Deleted credentials.
Rotating credentials
Regularly rotating your access keys is a critical part of credential management. You can do this with the aws-vault rotate <profile>
command as often as you like.
The minimal IAM policy required to rotate your own credentials is:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetUser"
],
"Resource": [
"arn:aws:iam::*:user/${aws:username}"
]
}
]
}
Managing Sessions
Executing a command
Running aws-vault exec
will run a command with AWS credentials.
When using exec, you may find it useful to use the builtin --
feature in bash, zsh and other POSIX shells. For example
aws-vault exec myprofile -- aws s3 ls
Using --
signifies the end of the aws-vault
options, and allows the shell autocomplete to kick in and offer autocompletions for the proceeding command.
If you use exec
without specifying a command, AWS Vault will create a new interactive subshell. Note that when creating an interactive subshell, bash, zsh and other POSIX shells will execute the ~/.bashrc
or ~/.zshrc
file. If you have local variables, functions or aliases (for example your PS1
prompt), ensure that they are defined in the rc file so they get executed when the subshell begins.
Logging into AWS console
You can use the aws-vault login
command to open a browser window and login to AWS Console for a given account:
$ aws-vault login work
If you have temporary STS credentials already available in your environment, you can have aws-vault use these credentials to sign you in. This is useful when you had to use something else than aws-vault to retrieve temporary credentials:
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN must be set in your environment prior to running the below
$ aws-vault login
Removing stored sessions
If you want to remove sessions managed by aws-vault
before they expire, you can do this with aws-vault clear
command.
You can also specify a profile to remove sessions for this profile only.
aws-vault clear [profile]
Using –no-session
AWS Vault will typically create temporary credentials using a combination of GetSessionToken
and AssumeRole
, depending on the config. The GetSessionToken
call is made with MFA if available, and the resulting session is cached in the backend vault and can be used to assume roles from different profiles without further MFA prompts.
If you wish to skip the GetSessionToken
call, you can use the --no-session
flag.
However, consider that if you use --no-session
with a profile using IAM credentials and NO role_arn
, then your IAM credentials will be directly exposed to the terminal/application you are running. This is the opposite of what you are normally trying to achieve by using AWS Vault. You can easily witness that by doing
aws-vault exec <iam_user_profile> -- env | grep AWS
You’ll see an AWS_ACCESS_KEY_ID
of the form ASIAxxxxxx
which is a temporary one. Doing
aws-vault exec <iam_user_profile> --no-session -- env | grep AWS
You’ll see your IAM user AWS_ACCESS_KEY_ID
of the form AKIAxxxxx
directly exposed, as well as the corresponding AWS_SECRET_KEY_ID
.
Session duration
If you try to assume a role from a temporary session or another role, AWS considers that as role chaining and limits your ability to assume the target role to 1h. Trying to use a duration longer than 1h may result in an error:
aws-vault: error: Failed to get credentials for default: ValidationError: The requested DurationSeconds exceeds the MaxSessionDuration set for this role.
status code: 400, request id: aa58fa50-4a5e-11e9-9566-293ea5c350ee
For that reason, AWS Vault will not use GetSessionToken
if --duration
or the role’s duration_seconds
is longer than 1h.
MFA
To enable MFA for a profile, specify the mfa_serial
in ~/.aws/config
. You can retrieve the MFA’s serial (ARN) in the web console, or you can usually derive it pretty easily using the format arn:aws:iam::[account-id]:mfa/[your-iam-username]
. If you have an account with an MFA associated, but you don’t provide the IAM, you are unable to call IAM services, even if you have the correct permissions to do so.
AWS Vault will attempt to re-use a GetSessionToken
between profiles that share a common mfa_serial
. In the following example, aws-vault will cache and re-use sessions between role1 and role2. This means you don’t have to continually enter MFA codes if the user is the same.
If you’re looking for the right value to put in mfa_serial, you can use aws iam list-mfa-devices
or you can find it in the AWS console.
[profile tom]
mfa_serial = arn:aws:iam::111111111111:mfa/tom
[profile role1]
source_profile = tom
role_arn = arn:aws:iam::22222222222:role/role1
mfa_serial = arn:aws:iam::111111111111:mfa/tom
[profile role2]
source_profile = tom
role_arn = arn:aws:iam::33333333333:role/role2
mfa_serial = arn:aws:iam::111111111111:mfa/tom
AWS Single Sign-On (AWS SSO)
If your organization uses AWS Single Sign-On (AWS SSO), AWS Vault provides a method for using the credential information defined by AWS SSO CLI v2. The configuration options are as follows:
sso_start_url
The URL that points to the organization’s AWS SSO user portal.sso_region
The AWS Region that contains the AWS SSO portal host. This is separate from, and can be a different region than the default CLI region parameter.sso_account_id
The AWS account ID that contains the IAM role that you want to use with this profile.sso_role_name
The name of the IAM role that defines the user’s permissions when using this profile.
Here is an example configuration using AWS SSO.
[profile Administrator-123456789012]
sso_start_url=https://aws-sso-portal.awsapps.com/start
sso_region=eu-west-1
sso_account_id=123456789012
sso_role_name=Administrator
Integration with ZSH and oh-my-zsh
I use the iTerm2 terminal configured with the ZSH shell. I also use the oh-my-zsh framework for my ZSH shell. This should work in any terminal that uses ZSH not just iTerm2. So any Unix-like operating system, MacOS, Linux, BSD and WSL2 on Windows. ‘Oh My Zsh’ is an open source community-driven framework for managing your ZSH configurations. Think of it as a community supported alias package for your terminal.
‘Oh My Zsh’ supports plugins and the plugin we will add is called zsh-aws-vault. It provides many convenient aliases to use when running commands that interact with the configured AWS profiles.
The first step in installing the above plugin is to clone and download it to the plugins directory:
$ cd ~/.oh-my-zsh/custom/plugins
$ git clone git@github.com:blimmer/zsh-aws-vault.git
Next, edit your ~/.zshrc file and add the new plugin to the plugins line. We will be adding a plugin for AWS Vault. So edit your plugins line to look something like this: (Here, I’m adding AWS Vault in addition to git and dotenv plugins):
plugins=(
git
dotenv
zsh-aws-vault
)
Usage with zsh-aws-vault
Here are the aliases that are added after you install the plugin for zsh:
Alias | Expression |
---|---|
av | aws-vault |
ave | aws-vault exec |
avl | aws-vault login |
avll | aws-vault login -s |
avli | aws-vault login in private browsing window |
avs | aws-vault server |
avsh | aws-vault exec $1 — zsh |
avp | list aws config / role ARNs |
We will use the following command to run the example above where we listed all S3 buckets in our account:
$ ave s3-read-user -- aws s3 ls
account_bucket-a
account_bucket-b
account_bucket-c
Sometimes you might not want to type extra commands each time you want to interact with your AWS account through the CLI. In such cases use the nifty avsh
command to create a shell for a given profile. Then any command you run in that shell will use the associated profile. Using the example above, we can create a shell with the s3-read-user
profile, then run any command without using the ave
or aws-vault
prefixes like we did above:
$ avsh s3-read-user
Now any command you run in that shell will use the associated profile from the previous command:
$ aws s3 ls
account_bucket-a
account_bucket-b
account_bucket-c
If you run the env
command at this point, you will see all the AWS environment variables created in your terminal. You can use the exit
command to go back to your regular shell and remove these variables from your shell environment.
$ env | grep AWS
AWS_VAULT=s3-read-user
AWS_DEFAULT_REGION=us-east-1
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=%%%
AWS_SECRET_ACCESS_KEY=%%%
AWS_SESSION_TOKEN=%%%
AWS_SECURITY_TOKEN=%%%
AWS_SESSION_EXPIRATION=2020-12-29T11:00:00Z
To exit from the temporary shell and back to your normal shell without the AWS environment variables, use the exit command:
$ exit