IAM User credentials with MFA

on
Jul 26, 2022
in

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.
Assume role using MFA Token
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.
Fetch STS Credentials then assume role
As you can see we split the process into 2 parts:

  1. Fetch the temporary credentials for the IAM User using MFA.
  2. 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 the mfa_serial and username. 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:

  1. List all available keys for the user, when 1 key is active rotation is possible!
  2. Create a new AccessKey and SecretAccessKey.
  3. Use the created keys to deactivate the old keys.
  4. Write the new keys to the ~/.aws/configuration file.
  5. 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!

Joris has been working with the AWS cloud since 2009 and focussing on building event driven architectures. While working with the cloud from (almost) the start he has seen most of the services being launched. Joris strongly believes in automation and infrastructure as code and is open to learn new things and experiment with them, because that is the way to learn and grow. In his spare time he enjoys running and runs a small micro brewery from his home.
Share this article: Tweet this post / Post on LinkedIn