Improve AWS security: protect your keys with ease

Andreas Wittig – 23 Oct 2015

As a DevOps engineer, I love to work with the AWS Command Line Interface (CLI) to control various AWS resources in an (half-)automated way. To be able to do so it is necessary to store access keys on my local machine. These access keys (access key ID and secret access key) are used to authenticate with AWS whenever I run a command with the help of the AWS CLI. I do my very best to keep my local machine secure, but nevertheless, I don’t think it is a good place to store my keys to AWS without any further security arrangements.

Locked green door

Michael already wrote about using MFA (multi-factor authentication) to add another layer of security in his blog post Your single AWS account is a serious risk. AWS supports MFA when logging in with the Management Console and for the use of the CLI as well. If you configure MFA for your IAM user, the access key is no longer sufficient to authenticate. Instead, the access key and a one-time password generated by a hardware token or a mobile app are needed. So it is a much smaller disaster if someone can steal the AWS keys from your local machine because these keys won’t unlock all your AWS accounts.

Using MFA with the AWS CLI is easy

1. Restrict access for IAM user

Attach the following IAM policy to an IAM user (or an IAM group).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "2",
            "Effect": "Allow",
            "Action": [
                "sts:GetSessionToken"
            ],
            "Resource": "*"
        }
    ]
}

With this policy the user is only allowed to perform the following actions: using STS to get temporary AWS keys and assuming an IAM role. But assuming a role is only possible after the IAM user is multi-factor authenticated.

Note: it is also possible to restrict the roles the user can assume. This is necessary if you are using multiple IAM roles within your AWS account or if other AWS accounts grant you to assume their roles.

2. Configure MFA for IAM user

It is necessary to configure an MFA device for the IAM user. It is possible to use the Management Console to do so. Select the IAM user and search for the Manage MFA device button. A click on this button will open a wizard that will guide you through the process of configuring an MFA device for the IAM user.

3. Create an IAM role

You need to create an IAM role next as the IAM user will need to assume a role to be able to control AWS resources from now on.

When using the wizard of the AWS Management Console to create a new IAM role you are asked to select a role type. Choose *Role for Cross-Account Access** and select *Provide access between AWS Accounts you own”.

alt

Enter your Account ID and enable MFA in the next step.

alt

Andreas and Michael Wittig

Please support our work!

We have published 327 articles, 41 podcast episodes, and 15 videos. It's all free and means a lot of work in our spare time.

Thanks to Alan Leech, Alex DeBrie, e9e4e5f0faef, Goran Opacic, jhoadley, Shawn Tolidano, Thorsten Hoeger, Todd Valentine, Vince Fulco, and all anonymous supporters for your help! We also want to thank all supporters who purchased a cloudonaut t-shirt. It gives us great pleasure to send our t-shirts all over the world.

With your help, we can continue to produce independent & high-quality content focused on AWS. Please support us!

Support us

Create an IAM role and attach an IAM policy granting access to the needed AWS resources. For DevOps engineers, it might be a good idea to use the managed IAM policy called PowerUserAccess.

4. Configure AWS CLI

You need to install and configure your AWS CLI first. It is now necessary to configure the AWS CLI in a way it uses the IAM role you created in step 3 and the MFA device you configured in step 2.

AWS access keys are stored under ~/.aws/credentials. Usually this looks similar to the following listing.

[default]
aws_access_key_id = ...
aws_secret_access_key = ...

The configuration for the AWS CLI is stored at ~/.aws/config and should look similar to the next listing.

[profile default]
region = us-east-1
output = json

The profile is named default in this case. It is possible that your profile uses another name. If so, please replace default with the name of your profile in the following.

To be able to assume a role with MFA you need to add the following snippet to your ~/.aws/config file. Replace $AccountNumber with your AWS account number, $IamRole with the name of the IAM role you created in step 3 and $MfaSerial with the ARN of the MFA device you created for the IAM user in step 2. You will be able to find the $MfaSerial if you open the IAM user in the Management Console searching for Multi-Factor Authentication Device.

[profile poweruser]
role_arn = arn:aws:iam::$AccountNumber:role/$IamRole
source_profile = default
mfa_serial = $MfaSerial

After you replaced the variables, the snippet should look similar to the following listing.

[profile poweruser]
role_arn = arn:aws:iam::111111111111:role/PowerUser
source_profile = default
mfa_serial = arn:aws:iam::111111111111:mfa/johndoe

5. Testing configuration

Everything is ready to be tested now. If you execute aws s3 ls --profile poweruser in your terminal the CLI will ask for your MFA code before it lists all S3 buckets.

You don’t need to re-enter the MFA token on every request. The temporary token is valid for 12 hours by default.

The AWS documentation contains more details about how to configure the AWS CLI to assume a rule and use MFA: Assuming a Role

Summary

It is possible to use multi-factor authentication when controlling AWS resources with the help of the CLI. The CLI supports MFA and assuming a role out of the box. This adds an additional layer of security: your AWS accounts won’t be compromised if someone can steal the AWS keys from your local machine.

Tags: aws security cli
Andreas Wittig

Andreas Wittig

I launched cloudonaut.io in 2015 with my brother Michael. Since then, we have published hundreds of articles, podcast episodes, and videos. It’s all free and means a lot of work in our spare time. We enjoy sharing our AWS knowledge with you.
Have you learned something new by reading, listening, or watching our content? If so, we kindly ask you to support us in producing high-quality & independent AWS content. We look forward to sharing our AWS knowledge with you.

Support us

Feedback? Questions? You can reach me via Email, Twitter, or LinkedIn.