When you use IAM user for programmatic access. You have an ACCESS_KEY
and a SECRET_ACCESS_KEY
. With these credentials you are able to interact with AWS. A common pattern is that you will use the IAM User to assume roles in the same or even in different AWS accounts. The CLI configuration would look something like this:
[profile my-role]
source_profile = default
role_arn = arn:aws:iam::111122223333:role/Administrator
mfa_serial = arn:aws:iam::111122223333:mfa/my-iam-user
But when you use this role for the first time. Or when the cached credentials are expired it will prompt for MFA token. When you use many accounts and profiles this becomes annoying. You could configure and use a longer session time on your roles. But you still need to enter your MFA token per role. In this blog post I will explain why this is and what you can do to avoid it!
How does it work?
So what happens under the hood? When you perform an cli command like:
aws s3 ls --profile=my-role
It will first check in the ~/.aws/cli/cache/
folder if there are credentials cached. If not or if the credentials are expired an assume-role
call is executed. Because we configured the default
source profile. It will use the default
credentials found in the ~/.aws/credentials
file.
[default]
aws_access_key_id = AKIAXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Because we configured an mfa_serial
under our profile in our ~/.aws/config
file. The AWS cli will prompt for the token and once given it will do the assume-role API call. If everything is fine temporary credentials are returned and these are cached. The problem with this approach is that it will be executed each time you need to assume a role. Therefor triggering an MFA prompt each time you use a role. For the first time or if the cached credentials are expired.
How can I avoid it?
You can avoid the MFA prompts by first fetching the temporary credentials of the IAM User using MFA. This will give you credentials that are MFA authenticated. And because they are already MFA authenticated. There is no need to provide the token during the assume-role API call. As you can see we split the process into 2 parts:
- Fetch the temporary credentials for the IAM User using MFA.
- Use the temporary credentials to assume the
my-role
role.
The magic behind this approach is because we have split them. You are able to repeat step 2 with other roles. This removes the MFA token prompt because we are already authenticated using MFA.
To make this easier I wrote a small cli tool called aws-iam-login that helps you with this!
It only needs to know themfa_serial
andusername
. You can retrieve these if you execute:
aws-iam-login default init
This command will fetch the ARN of the caller identity. Based on this identity we will determine the username and mfa_serial of the IAM User. These will then be stored in the ~/.aws/credentials
file. For example:
[default]
aws_access_key_id = AKIAXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
mfa_serial = arn:aws:iam::111122223333:mfa/my-iam-user
username = my-iam-user
Now you can use the tool as followed:
aws-iam-login default
This authenticates against the AWS API. And request temporary credentials from AWS using your MFA Token. These credentials are then stored as <profile-name>-sts
. For example:
[default-sts]
aws_access_key_id = ASIAXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
aws_session_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
expiration = 2022-07-25 19:00:00+00:00
So if you now use the following in your ~/.aws/config
file:
[profile my-role]
source_profile = default-sts
role_arn = arn:aws:iam::111122223333:role/Administrator
You will now use the temporary credentials defined in the ~/.aws/credentials
file. When the temporary credentials become invalid. Re-run the aws-iam-login default
command and new credentials will be fetched.
Rotating your credentials
Next to helping you assume roles aws-iam-login can help you with more! It can rotate your credentials for you! You can do this with the following command:
aws-iam-login default rotate
And the tool will:
- List all available keys for the user, when 1 key is active rotation is possible!
- Create a new AccessKey and SecretAccessKey.
- Use the created keys to deactivate the old keys.
- Write the new keys to the
~/.aws/configuration
file. - Delete the old keys.
Conclusion
By using the temporary credentials of the IAM user. You are not prompted to enter your MFA token every time. And aws-iam-login can help you with that!