🎉 We are launching a new weekly show: Hot off the Cloud

🎉 We are launching a new weekly show

Your single AWS account is a serious risk

Michael WittigUpdated 30 Aug 2016

Your AWS account is one of the most valuable things you own if you run a business on AWS. If you only own a single AWS account, you’re facing a serious security risk! The post will show you why this a problem and how you can solve it.

This post received over 300 points and 100 comments on Hacker News.

The risky default: a single AWS account

A single AWS account contains IAM users together with EC2 virtual servers, S3 buckets, RDS databases, and everything else you need to run your business. You have two ways to log in to your account: AWS Management Console (using username + password) or AWS access credentials used by the CLI and SDKs. The figure demonstrates how this works.

Single AWS account

When you type something like …

$ aws ec2 describe-instances

… into your terminal, your AWS access credentials (usually residing somewhere at ~/.aws/) are used to authenticate your request. You authenticate as an IAM user. The IAM user in most cases has AdministratorAccess, which means you can do anything. Why? You need to be able to administer all services. If someone gets access to your AWS access credentials, you’re in trouble.

You can improve this situation two ways.

1st improvement: Don’t use AdministratorAccess

To follow the principle of least privilege, it’s very unlikely that AdministratorAccess is what you need. PowerUserAccess is an improvement, because it doesn’t let you use the IAM service. Much better is having ReadOnlyAccess and using writing permissions only when needed. But that’s difficult to implement using IAM users. You need to create a user for each “least privilege,” and you need to generate access credentials for each user. Such a setup quickly becomes unmanageable if you aren’t the only user in your AWS account. I’ll call this security debt.

2nd improvement: Use multi-factor authentication

AWS provides excellent support for multi-factor authentication (MFA). You can use a hardware device or a software device to generate a token. Your password or access credentials together with the MFA token are then used to authenticate. Getting access to your account is now much more difficult.

Read on to learn how to implement these improvements.

Separating concerns with a bastion account

Instead of a single AWS account, you create another account. I’ll call this your bastion account. The bastion account contains only your IAM users — nothing else. The figure illustrates the idea.

Bastion AWS account


Looking for a new challenge?

  • tecRacer

    Cloud Consultant • AWS Migrations

    tecRacer • Premier AWS Consulting Partner • Germany, Austria, Portugal, and Switzerland
    Assessment Transformation Change Management
  • DEMICON

    Senior Lead Full Stack Developer

    DEMICON • AWS Advanced Consulting Partner • Remote
    AWS JavaScript/TypeScript Angular React

IAM users in the bastion account are very limited. They can only get temporary credentials and assume a role. Implement this by creating a group in the bastion account with an inline policy, as follows:

{
"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": "*"
    }
]
}

Assign this group to all the IAM users in the bastion account. Make sure they don’t have any other policies attached!

The first Statement lets a user assume a role (but only if the request is authenticated using MFA). The second Statement lets a user get a temporary session by providing the MFA token. Let’s look at how this works.

The secure solution: MFA with role delegation

It’s time to summarize the setup: How does it work? The following figure shows the MFA authentication and role delegation flow.

MFA with role delegation

  1. You have AWS access credentials for your IAM user in the bastion account on your machine (usually in ~/.aws/ or in your environment variables). You make a call to the AWS API to get temporary credentials by providing an MFA token. If the MFA token is valid, you’ve created a short-lived session for your IAM user in the bastion account.

  2. You receive temporary credentials to authenticate as your IAM user.

  3. With the temporary credentials, you can assume a role in another account (this wasn’t possible before because assuming a role is only allowed for after authenticating with MFA). To assume a role in another account, the role must explicitly be allowed to be used with your account! The maximum permissions a role should have is PowerUserAccess. Don’t allow the role to interact with IAM!

  4. You receive temporary credentials and can begin working with your AWS account.

Implementation

The AWS CLI supports MFA authentication by default. Andreas has written up detailed instructions here.

This blog post has been translated into German: Ein einziger AWS Account ist ein ernsthaftes Risiko.

Become a cloudonaut supporter

Michael Wittig

Michael Wittig ( Email, Twitter, or LinkedIn )

We launched the cloudonaut blog in 2015. Since then, we have published 360 articles, 49 podcast episodes, and 48 videos. It's all free and means a lot of work in our spare time. We enjoy sharing our AWS knowledge with you.

Please support us

Have you learned something new by reading, listening, or watching our content? With your help, we can spend enough time to keep publishing great content in the future. Learn more

$
Amount must be a multriply of 5. E.g, 5, 10, 15.

Thanks to Alan Leech, Alex DeBrie, ANTHONY RAITI, Christopher Hipwell, Jaap-Jan Frans, Jason Yorty, Jeff Finley, Jens Gehring, jhoadley, Johannes Grumböck, Johannes Konings, John Culkin, Jonas Mellquist, Juraj Martinka, Kamil Oboril, Ken Snyder, Markus Ellers, Ross Mohan, Ross Mohan, sam onaga, Satyendra Sharma, Shawn Tolidano, Simon Devlin, Thorsten Hoeger, Todd Valentine, Victor Grenu, and all anonymous supporters for your help! We also want to thank all supporters who purchased a cloudonaut t-shirt.