Solving AWS Multi-account Access Control in 2 Steps

First assumption: you have multiple AWS accounts. If you don’t, you should — at the very least, you need a management account (that runs no workloads) and one account per environment. For a small startup, 3 accounts will suffice — management, staging and production. For a big organization with many teams and products, you should multiply this by the number of those products/teams, and add some additional “central” accounts — be it for networking, SDLC tools or other purposes.

Point being: you really should not keep everything in a single account, it makes your setup less secure, harder to monitor and adjust the billing, harder to properly organize in terms of access for humans and robots.

Read Establishing your best practice AWS environment for some of the best practices on organizing your AWS accounts.

The word “account” is probably a bit misleading. Google Cloud Platform uses the word “project”, which (at least to me) sounds like a better word to describe a “group of cloud resources with their own purpose and security and cost boundary”. Another thing that GCP does better from the user experience perspective is how you switch between projects and separate accounts. Your Google account is what gets permissions to the project. Even if you have multiple Google accounts, you can easily switch between them — this point is probably not that critical for the majority of users, but for the expert team at mkdev it saves a lot of time switching between different environments of different customers.

On AWS, things were always a bit messy in these regards. What used to be the standard for many years, is the following:

  • Configure AWS IAM Federation in your management account;
  • Configure different IAM roles in each account, each role mapping to some level of permissions (admin role, developer role etc);
  • Allow federated users to assume IAM roles in target accounts.

Once you create this setup (hopefully with automation, with Terraform, for example), you just need to assume roles locally with the CLI, or switch roles via the web browser. Many organizations are “stuck” with this setup, primary reason being that AWS SSO exists only since 2017 and is not actively advertised. I noticed with many mkdev customers that there is even no awareness of existence of AWS SSO.

Let me provide a quick 2-step guide on how to “solve” user access for AWS accounts once and for all. It will be most beneficial for new environments. If you already have an automated setup with IAM Federation for dozens of accounts, skip to Step 2.

Step 1: Setup AWS Single Sign-On

AWS SSO service allows you to configure all your users and groups in a single place, in your management account. You can then map users and groups to AWS Accounts via Permission Sets, telling that DevOps group needs to get Admin permissions set in all accounts, and Developer group only gets Admin in Staging AWS account, and Read Only in Production account.

The key here is a “single place” — once you have AWS Organization configured, your complete user management happens in a management account. You don’t need to create IAM Roles in each child account, there is no need for extra cross-account automation for human access. AWS SSO itself can be automated as well, with Terraform or anything else, but this time automation belongs to a single management AWS account.

This is only relevant for humans. For cross-account access for robots you still need to use the other way.

You can connect AWS SSO to external Identity Provider, be it Active Directory or Okta. You can also manage access to external applications with AWS SSO — users can login to DataDog via SSO portal, for example.

Under the hood, AWS SSO automates same things that you would do otherwise — it will create IAM roles in each target account, with permissions matching the permission set. There is no magic, IAM is still there and it works as before. AWS SSO just adds an extra layer, centrally management component that removes the pain of setting this all up on your own.

The best part comes when you start using AWS SSO locally, with AWS CLI or tools like Terraform. You can create a configuration file like this:

[default]
region = us-east-1


[profile mkdev-staging]
sso_start_url = https://mkdev.awsapps.com/start#/
sso_region = us-east-1
sso_account_id = STAGING_ACCOUNT_ID
sso_role_name = AdministratorAccess
region = us-east-1


[profile mkdev-production]
sso_start_url = https://mkdev.awsapps.com/start#/
sso_region = us-east-1
sso_account_id = PRODUCTION_ACCOUNT_ID
sso_role_name = AdministratorAccess
region = us-east-1


[profile mkdev-mgmt]
sso_start_url = https://mkdev.awsapps.com/start#/
sso_region = us-east-1
sso_account_id = MANAGEMENT_ACCOUNT_ID
sso_role_name = AdministratorAccess
region = us-east-1

And then run a command like this:

aws sso login --profile mkdev-mgmt

This will log you into AWS SSO, meaning it will log you into all AWS accounts that you have access to. You do not need to assume individual roles. Instead, after you do aws sso login (once every 12 hours at most), you can do things like:

aws s3 ls --profile mkdev-staging
aws s3 ls --profile mkdev-production

It works like a charm with Terraform as well, you only need to feed the profile name to the provider:

provider "aws" {
  region = "us-east-1"
  profile = "mkdev-${terraform.workspace}"
}

Note that huge benefit of AWS SSO is that you never need to store any Access Keys on your disk. aws sso login takes you through authentication in the browser and then saves temporal token on your disk. No static credentials anymore.

While this alone already solves most of the challenges with proper multi-account access configuration, there is a way to make it even nicer.

Step 2: Setup Granted

When you have many AWS accounts, or (the case for mkdev) many customers with many AWS accounts, you end up switching between those accounts in the browser all the time. By default, you can be logged into only one account at a time. Imagine you have 5 tabs open for staging account and now you want to jump to the dev account. Once you switch to the dev, all 5 tabs lose their session, with a nice warning from AWS.

Granted solves this. It’s a neat CLI with a browser extension, that allows you to keep tabs with different AWS Accounts open at the same time. Depending on the browser, you will get a visual hint which tab belongs to which account. It’s a life saviour if you have more than 3 accounts.

Granted is not just for the browser — it also lets you quickly switch between profiles, and adds an encryption for SSO tokens on the disk, by using native OS capabilities. Both of those features are also nice, but not as amazing as having multiple different AWS accounts available without any extra Incognito windows and different browsers.

Summary

AWS SSO and Granted combined bring you both more secure setup and improve productivity significantly. It never felt nicer to use AWS in multi-account (in other words, the only valid ones) environments.