How to use aws-vault to securely access multiple AWS accounts

Andrei Maksimov

Andrei Maksimov


As soon as you start working with more than one project or organization in the AWS cloud, the first question you may have is how to manage awscli credentials and have to use them easily and securely to get access to all your AWS accounts and environments. This article will cover aws-vault – a tool to store and access AWS credentials in a development environment securely.

The problem

I always was not a big fan of ~/.aws/credentials file, because every single time I was coming to a new customer, I needed to open this file for the edit to add new credentials. As a result, I constantly had a feeling that I displayed all my existing credentials to all security cameras in the office. God, bless the inventor of the privacy screens!

The second problem with credentials is that they need to be renewed from time to time. The more accounts you have, the more effort you spend on credentials rotation.

And the third problem – is assuming roles in terminal sessions and working in several different environments at the same time.


As a solution for the first two problems, not too far ago, I started using:

As a solution for the last two problems, I found that the following tooling stack suits most of my needs:

Managing AWS credentials

Here’s a quick getting started guide.


I’m assuming here that you already have zsh and oh-my-zsh installed. 😎

Let’s install aws-vault. Here’s the complete list of installation steps for most available platforms.

We’ll be doing everything for OS X (macOS):

brew cask install aws-vault

Choosing aws-vault backend

aws-vault supports several backends to store your credentials. My preference is to use an encrypted file. So, you need to add the following variable to your ~/.zshrc:

export AWS_VAULT_BACKEND="file"

Moving credentials to aws-vault

Now open your ~/.aws/credentials file. For every existing profile, add credentials to aws-vault.

cat ~/.aws/credentials

aws-vault add profile_1

aws-vault add profile_2

Now, aws-vault has AWS_VAULT_FILE_PASSPHRASE variable, which can be used to stop aws-vault from asking your vault password over and over again. There’re two ways to use it:

Not secure way

Add the following variable to your ~/.zshrc or ~/.bashrc file, to prevent aws-vault from asking for your password every single time:

export AWS_VAULT_FILE_PASSPHRASE="my_strong_password"

Secure way

Instead of storing AWS_VAULT_FILE_PASSPHRASE variable in .*rc files, you may create AWS Systems Manager Parameter Store SecureString parameter, which contains your aws-vault password:

aws ssm put-parameter \
  --name '/laptop/aws-vault/password' \
  --description 'aws-vault password on my laptop' \
  --value 'my_super_secret_password' \
  --type SecureString

Let’s create a wrapper script, which will call aws-vault call aws-vault and set up AWS_VAULT_FILE_PASSPHRASE with a necessary value from AWS Systems Manager Parameter Store:

mkdir -p $HOME/bin
cat > $HOME/bin/ <<- EOF
#!/usr/bin/env bash

export PROFILE=$1
export AWS_VAULT_FILE_PASSPHRASE=$(aws ssm get-parameters --profile default --names '/laptop/aws-vault/password' --with-decryption --query 'Parameters[0].Value' --output text)

aws-vault exec -j $PROFILE

chmod +x $HOME/bin/

Now you may use this wrapper at ~/.aws/config like that:

[profile my_new_profile]
credential_process = ~/bin/ my_new_profile

You may rename ~/.aws/credentials and later on completely delete it as soon as you test everything.

Switching AWS Profiles

To list all your AWS profiles, just type:

aws-vault list

Great, now you can easily switch your environment and see where you’re working:

aws-vault exec --duration 8h default

Here’s how it finally looks like:


Role-based approach

Well, ok, we just moved all our AWS credentials to a secure vault and configured our terminal to display our current aws-vault session. Now it’s time to discuss how we can improve the solution even more.

Multi-account organization

One of the best practices for organizing AWS users’ access to different AWS accounts – is managing all IAM users in one AWS account and providing access to other AWS accounts by allowing them to consume roles (sts:AssumeRole API call) from that accounts.

Here’s the typical AWS Organization example:


AWS provided a great explanation of How to Use a Single IAM User to Easily Access All Your Accounts by Using the AWS CLI in their blog post, describing the role consuming process and awscli configuration. I’ll not copy-paste them. Instead, we’ll concentrate on the aws-vault configuration to do something similar, but without ~/.aws/credentials file.

Assuming you already have all the necessary grants and permissions between your accounts. If not, here’s the great article on that topic – Tutorial: Delegate Access Across AWS Accounts Using IAM Roles.

Default profile setup

You should already have your default profile setup in place at file. Probably, it looks something like that:

[profile default]
region = us-east-1

Let’s configure aws-vault as a credential source for our default profile:

[profile default]
region = us-east-1
credential_process = /usr/local/bin/aws-vault exec -j default

Now, if you grant permissions to your user or role from default profile to assume AWS role from another account, you’ll be able to specify new profiles configuration like that:

[profile default]
region = us-east-1
credential_process = /usr/local/bin/aws-vault exec -j default
mfa_serial = arn:aws:iam:::mfa/admin

[profile default]
region = us-east-1
credential_process = /usr/local/bin/aws-vault exec -j default
mfa_serial = arn:aws:iam:::mfa/admin

[profile account_1_role_admin]
region = us-east-1
role_arn = arn:aws:iam:::role/admin
source_profile = default

[profile account_2_role_qa]
region = us-east-1
role_arn = arn:aws:iam:::role/qa
source_profile = default

source_profile configuration option will tell awscli which account to use to grab a role for any given profile.



The fastest way to test that you’re able to assume the role is to call:

aws sts get-caller-identify

You should see something similar for your default profile:

    "Account": "01234567890",
    "Arn": "arn:aws:iam::01234567890:user/admin"

To test any other profile call:

aws sts get-caller-identity --profile account_1_role_admin

You should see output similar to the following:

    "UserId": "AROALKJHGFGDFV3IR2VSI:botocore-session-1584897134",
    "Account": "012345678901",
    "Arn": "arn:aws:sts::012345678901:assumed-role/admin/botocore-session-1584897134"

Assuming AWS account role

To assume the role from any AWS account which you have in your aws-vault, execute the following commands:

aws-vault ls
aws-vault exec --duration 8h default

Here, we’re assuming a role associated with the default profile for 8 hours.

Bonus: Passwordless AWS Web console login

As a small bonus to those of you, who came to an end, here’s how to login to the AWS web console for every given profile:

aws-vault ls
aws-vault login --duration 8h default


Using zshaws-vault, and AWS sts:AssumeRole feature together can significantly simplify and make more secure management of multiple AWS accounts and their credentials.

If you like the article, please, feel free to spread it to the world. And of course, if you have any questions, suggestions, or comments, feel free to use Disqus below.

Stay tuned!

How useful was this post?

Click on a star to rate it!

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Want to be an author of another post?

We’re looking for skilled technical authors for our blog!

Leave a comment

If you’d like to ask a question about the code or piece of configuration, feel free to use or a similar tool as Facebook comments are breaking code formatting.