AWS Multi-factor Authentication on the Command Line using AWS-Vault
Slow Your Scroll - The Introduction
Having some form of Multi-factor Authentication (MFA) enabled, be it sms, an authenticator app, or yubikey, is an important aspect of the account security policy that you enforce on your AWS Account. User Credentials (username and password) and MFA give users a higher degree of certainty that the AWS Console user accessing resources within the account is in fact who they say they are. As developers and system administrators it\'s important that we extend this degree of certainty to the command line (cli) where we interact with aws resources programmatically using access keys. This can be done using aws-vault a cli tool to securely store and access AWS credentials in a development environment.
To Install
MacOS
brew install --cask aws-vault
Windows
choco install aws-vault
Linux
please refer to install section of aws-vault docs for your linux distribution
Getting Started - A Quick Look at the AWS Config File
Open ~/.aws/config
.
; Caktus Managed AWS
[profile caktus]
credential_process=aws-vault exec --no-session --json caktus
[profile caktus-mfa]
mfa_serial=arn:aws:iam::<caktus-account-id>:mfa/<username>
source_profile=caktus
region=us-east-1
output=json
; Assume Role setup
[profile <role-profile>]
mfa_serial=arn:aws:iam::<caktus-account-id>:mfa/<username>
role_arn=arn:aws:iam::<role-profile-account-id>:role/<assumed-role>
source_profile=caktus
region=us-east-1
[profile <role-profile>]
mfa_serial=arn:aws:iam::<caktus-account-id>:mfa/<username>
role_arn=arn:aws:iam::<role-profile-account-id>:role/<assumed-role>
source_profile=caktus
At the end of this setup you should have both a caktus profile and mfa
profile for main account access listed in your aws config file. Assuming
roles in other accounts should follow the above syntax that sets
caktus
as the source_profile
for the
<role_profile>
. All MFA protected profiles need to have your mfa_serial
specified for it.
Both Main Account setup
and Assume Role setup
can
be repeated as many times as needed.
You will need to comment out (;
)
or delete an existing caktus
profile to allow aws-vault
to manage
this profile in the config file. No changes are needed to be done
to the credentials file.
Caktus Account setup
- Setup
caktus
by runningaws-vault add caktus
.
$ aws-vault add caktus
Enter Access Key ID: <aws-access-key-id>
Enter Secret Access Key: <aws-secret-access-key>
Added credentials to profile "caktus" in vault
After providing your aws keys you will be prompted by KeyChain on MacOS to set a password. If you are on another operating system or would like to change the behavior of the vaulting backend please refer to this section of the docs.
In the ~/.aws/config
file, you should see the newly created
caktus
profile.
[profile caktus]
-
Set the
credentials_process
variable to instructaws-vault
to expose thecaktus
profile's access keys to the terminal.[profile caktus] credential_process=aws-vault exec --no-session --json caktus
-
Setup
caktus-mfa
in~/.aws/config
file
[profile caktus]
credential_process=aws-vault exec --no-session --json caktus
[profile caktus-mfa]
mfa_serial=arn:aws:iam::<account-id>:mfa/<username>
source_profile=caktus
region=us-east-1
output=json
Setting mfa_serial
for the caktus-mfa profile:
- Copy your IAM ARN for your
user: arn:aws:iam::<caktus-account-id>:user/<username>
- Replace user
with mfa
: arn:aws:iam::<caktus-account-id>:mfa/<username>
The caktus-mfa
profile's source profile
should be set to caktus
.
caktus-mfa
can just be added to the aws config file.
aws-vault add caktus-mfa
is not used. (This is also true for <role-profile>
s).
- Test the configuration
$ aws-vault exec caktus-mfa
Enter MFA code for arn:aws:iam::<caktus-account-id>:mfa/<username>: <Enter Code from MFA Device>
# Now authenticated and aws-vault session has been created
$ env | grep AWS
AWS_VAULT=caktus-mfa
...
...
...
- Assuming Roles from the Caktus Account
[profile <role-profile>]
mfa_serial=arn:aws:iam::<caktus-account-id>:mfa/<username>
role_arn=arn:aws:iam::<role-profile-account-id>:role/<assumed-role>
source_profile=caktus
region=us-east-1
Asumming roles will follow the above pattern. Check with the lead developer for the particular project you are joining
to get the <role-profile-account-id>
and <assumed-role>
that you will be assuming. For example, here is
how you would update ~/.aws/config
to assume the role assoicated with the saguaro-cluster
.
[profile saguaro-cluster]
mfa_serial=arn:aws:iam::<caktus-account-id>:mfa/<username>
role_arn=arn:aws:iam::<saguaro-cluster-account-id>:role/CaktusAccountAccessRole-Admins
source_profile=caktus
region=us-east-1
- Assume the Role
# Assumption: You have already authenticated by running "aws-vault exec caktus-mfa".
# Let's check
$ env | grep AWS
AWS_VAULT=caktus-mfa
...
...
# Let's unset the AWS_VAULT environment variable
$ unset AWS_VAULT
# Let's clearn the aws-vault's session
$ aws-vault clear
Cleared 1 sessions.
# let's switch to the saguaro-cluster role
$ aws-vault exec saguaro-cluster
Enter MFA code for arn:aws:iam::<saguaro-cluster-account-id>:mfa/<username>
# Ensure that you have access to the AWS Account
$ aws s3 ls
<list of s3 buckets within the saguaro-cluster account>
- If you are switching profiles, make sure to run
unset AWS_VAULT
, andaws-vault clear
before runningaws-vault exec <role_profile>
. -
If
AWS_VAULT
is not set then you can assume whichever mfa-enabled profile you would like. -
Caktus CI/CD Pipeline
AWS Vault does not replace the need to set AWS_PROFILE
when running manual deployments, ansible scripts, or developing locally.
Make sure to export AWS_PROFILE
when deploying/scripting resources.
Recommended Background Reading
If you would like to have a fuller understanding of what\'s going on under the hood, I recommended these resources.
Resources: - Kyle Knapp\'s 2017 AWS Reinvent talk - AWS Knowledge Center: How do I use an MFA token to authenticate access to my AWS resources through the AWS CLI? - Sourcing credentials with an external process