How should we design user access to multiple AWS accounts? As organizations scale, they tend to centralize identity with SSO SAML federation, but there are two patterns for federation with AWS.
Hub-and-spoke: users assume federated roles into a single AWS “identity account” and perform a second role assumption into sub-accounts
Direct: users assume federated roles into AWS sub-accounts directly
Let’s look at examples of each and tradeoffs between the two.
Hub-and-spoke AWS IAM federation
AWS Multiple Account Security Strategy from AWS Answers describes a hub-and-spoke model where IAM Groups of IAM users can assume roles from a central identity account.
If you use IAM users instead of federation, an identity account has obvious advantages for onboarding and offboarding users, establishing MFA, etc.
For cross-account IAM roles in federated use cases, AWS Answers points to the now-archived cross-account-manager. This tool builds a federated “hub-and-spoke” model with per-account roles that can be assumed from the identity account.
There are real-world federated hub-and-spoke AWS IAM multi-account setups. Segment’s Secure access to 100 AWS accounts article describes per-team “hub” identity accounts with sub-accounts. The aws-iam-generator project from AWS Labs implements hub-and-spoke, although there’s an open issue to support direct federation. A Reddit commenter described the benefits of automating changes with a single AWS account in a hub-and-spoke model:
We have security groups in AD that are linked to roles that are managed via SSO across accounts… It’s so much easier to manage them across accounts this way vs traditional SSO with a cross account IAM role per account (have to change that role on all 30+ accounts).
CloudConformity even has a “high” risk finding for not using AWS Multi-Account Centralized Management, which looks like hub-and-spoke.
Direct AWS IAM federation
AWS Control Tower is an example of direct federation, where each account has an AWS SSO identity provider configured. If you use AWS Control Tower out of the box, you use AWS SSO to sign in to each AWS sub-account directly via federation. There is no “identity account”.
This is how AWS SSO is configured in Control Tower, but what if you use a different identity provider? In the AWS Management and Operations Week lab “Use Okta with Control Tower”, they integrate Okta with direct federation using a CloudFormation StackSet to deploy an identity provider and roles to sub-accounts. They mention an identity account, but it’s only for the IAM user that Okta requires to list roles as part of the integration.
AWS Landing Zone is a multi-account architecture like Control Tower, and without an easily determinable reference architecture it’s difficult to say, but it appears to support some hub-and-spoke like functionality with cross-account security roles.
So, with all of these examples on each side, how do you decide whether you should use hub-and-spoke or direct model?
The source of the “hub-and-spoke” and “direct” terminology is a 2016 Re:invent workshop “Choose Your Own SAML Adventure: A Self-Directed Journey to AWS Identity Federation Mastery”. The author lists four reasons why they prefer the direct model:
- Corporate directory is the sole source of truth, as opposed to having access relationships defined in AWS for hub-and-spoke.
- Users can have access to a subset of accounts more easily than in hub-and-spoke.
- User experience is better — users require only a single “bookmark” to get to a specific account/role, rather than needing to use different bookmarks
- CLI and API automation don’t require the “extra hop” of assuming two roles to get the credentials necessary for operating in an account.
I see two major differences: the simplicity of assuming roles and the challenge of automating new account creation.
Hub-and-spoke requires two STS assume-role calls for users to get useful credentials.
Development tools using AWS SDKs support AWS configuration files that specify a chain of source “assume role” profiles, but since you’re logged into two roles simultaneously you need at least one named AWS profile, which requires passing the AWS_PROFILE variable to underlying libraries. This adds complexity to the already convoluted AWS credential detection logic that varies across different SDK versions and languages.
You also have two SessionDurations to deal with, which have to be set independently if you want to them to be different than the default. Don’t forget to thread the federated user identity through with RoleSessionName to get the friendly IAM name for logging and auditing purposes. The abstraction gap of the identity account is surface area for complexity to the SSO user experience.
New account bootstrapping
The more AWS accounts you create, the more you’ll want to automate a security baseline including IAM configuration. To automate the federated IAM parts of an account when you have a hub-and-spoke model, you only need to update the “hub” IAM roles to allow access to those roles in the new account.
If you have a direct model, you’ll need to automate the deployment of the identity provider to the new AWS account, which is only supported via a third-party CloudFormation custom resource. You also have to figure out how to update your SAML identity provider (e.g. Okta, AWS SSO, Jumpcloud) to return the SAMLRoleAttribute for the new role to users or groups that can access it. This may be difficult if you don’t already have automation in place that can access these systems. AWS SSO doesn’t even have an API, so there will currently be some manual step for new account creation if you use it. If you have more familiarity automating AWS services than your identity provider, this may be a benefit of a hub-and-spoke model.
As with many aspects of architecture using AWS, there are multiple ways to achieve a multi-account federated AWS IAM setup. If people access AWS through complex CLI or SDK interactions, you may want to simplify the role assumption process with a direct model. If you plan on automating the creation of hundreds or thousands of AWS accounts, a hub-and-spoke model may be a better choice.
Are there other tradeoffs that I missed? Let me know on Twitter @alsmola.