lilpacy.infoJA
AWS CLI SSO Setup for Multiple Accounts: The Two-Layer sso-session and profile Structure

AWS CLI SSO Setup for Multiple Accounts: The Two-Layer sso-session and profile Structure


TL;DR

  • AWS CLI SSO configuration becomes much clearer when you view it as a two-layer structure: [sso-session ...] (where to log in) and [profile ...] (account + role)
  • Use the aws configure sso interactive wizard for the initial setup; for adding additional profiles, just hand-edit ~/.aws/config by copy-pasting
  • Day-to-day, you only need aws sso login --profile <name> to log in and aws sts get-caller-identity --profile <name> to verify
  • Profiles that share the same sso_session are activated together by a single login. If you don’t want to specify --profile every time, use AWS_PROFILE
  • The legacy format (with sso_start_url written directly in a profile) is easier to manage once you migrate it to the sso-session format

What We Want to Do

A common scenario is wanting to switch between multiple AWS accounts from the CLI, for example:

  • A sandbox account
  • A root (management) account
  • A production-grade workload account
  • A staging-grade workload account

In AWS CLI, you define each one as a profile so you can switch between them per command using --profile. To work in the sandbox account, you log in like this.

aws sso login --profile sandbox-example

And to confirm your login state, like this.

aws sts get-caller-identity --profile sandbox-example

That much is well-known and simple, but I always found myself googling things like “wait, what do I write where for profile?” or “how is that different from sso-session?” — so I’m writing this as a personal reference.

Should You Hand-Write the Config?

The bottom line: let aws configure sso handle the initial setup. The AWS CLI ships with an interactive wizard for IAM Identity Center that walks you through every required field.

aws configure sso

The wizard asks for things like:

  • SSO session name
  • SSO start URL
  • SSO region
  • SSO registration scopes
  • AWS account
  • permission set / role
  • CLI default client Region
  • CLI default output format
  • CLI profile name

When the wizard finishes, it automatically writes [sso-session ...] and [profile ...] blocks into ~/.aws/config.

So the flow looks like this.

flowchart LR
  A[aws configure sso] --> B[Enter SSO info interactively]
  B --> C[~/.aws/config gets<br>sso-session and profile]
  C --> D[Tweak profile name<br>or region if needed]

That said, if you already have one profile and you just want to add another profile that uses the same sso-session, copying an existing block and swapping out only sso_account_id and the profile name is faster than rerunning the wizard. Use the wizard for the first profile, hand-copy for additional ones — that split has worked fine for me.

The Roles of sso-session and profile

When using SSO, the structure of ~/.aws/config is split into two layers.

  1. The shared settings for the SSO login itself → [sso-session ...]
  2. The per-account, per-role settings → [profile ...]

[sso-session ...] is the layer that decides which IAM Identity Center to log into. [profile ...] is the layer that decides which AWS account and which role to use under that login — that framing makes things easier to organize.

Concretely, ~/.aws/config looks like this (URLs and IDs are anonymized).

[sso-session example-operator]
sso_start_url = https://example.awsapps.com/start/#
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access

[profile sandbox-example]
sso_session = example-operator
sso_account_id = 111111111111
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[profile root-example]
sso_session = example-operator
sso_account_id = 222222222222
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[profile workload-prd]
sso_session = example-operator
sso_account_id = 333333333333
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[profile workload-stg]
sso_session = example-operator
sso_account_id = 444444444444
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

If you redraw this configuration as a tree, it looks like this.

flowchart TD
  S[sso-session: example-operator<br>start_url + region + scopes]
  S --> P1[profile: sandbox-example<br>account: 111111111111<br>role: AdministratorAccess]
  S --> P2[profile: root-example<br>account: 222222222222<br>role: AdministratorAccess]
  S --> P3[profile: workload-prd<br>account: 333333333333<br>role: AdministratorAccess]
  S --> P4[profile: workload-stg<br>account: 444444444444<br>role: AdministratorAccess]

example-operator holds the shared SSO login settings, and sandbox-example and friends are the profiles you actually pass to AWS CLI. The key point is that multiple profiles reference the same sso-session (we’ll see why this matters for shared logins below).

Reading Each Block

sso-session block

[sso-session example-operator]
sso_start_url = https://example.awsapps.com/start/#
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access

What each key means:

  • [sso-session example-operator] — the name of this SSO session; profiles refer to it by this name
  • sso_start_url — the access portal URL for IAM Identity Center
  • sso_region — the region where IAM Identity Center is running (e.g. ap-northeast-1 if you operate in Tokyo)
  • sso_registration_scopes — the scope the AWS CLI uses to access account information via SSO; usually sso:account:access

profile block

[profile sandbox-example]
sso_session = example-operator
sso_account_id = 111111111111
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

Read this as: “Using the SSO session named example-operator, operate as the AdministratorAccess role in AWS account 111111111111. The default region is ap-northeast-1 and the CLI output format is json.” The crucial part is sso_session = example-operator, which references the [sso-session ...] block.

Logging In and Verifying

Once profiles are defined, the only two commands you need day-to-day are these.

Log in like this.

aws sso login --profile sandbox-example

Running this opens a browser and asks you to log into IAM Identity Center. On success, the AWS CLI caches temporary credentials and you can call AWS APIs under that profile.

Verify like this.

aws sts get-caller-identity --profile sandbox-example

On success, it returns the AWS account ID and the role ARN you’re currently using. It’s the canonical command for quickly confirming you ended up in the account you intended.

For other profiles, just swap the profile name.

aws sso login --profile root-example
aws sso login --profile workload-prd
aws sso login --profile workload-stg

aws sts get-caller-identity --profile root-example
aws sts get-caller-identity --profile workload-prd
aws sts get-caller-identity --profile workload-stg

Profiles Sharing the Same sso-session Share Logins

In the example above, every profile references sso_session = example-operator.

[profile sandbox-example]
sso_session = example-operator

[profile root-example]
sso_session = example-operator

[profile workload-prd]
sso_session = example-operator

In this setup, if you log in once via sandbox-example, you can immediately run aws sts get-caller-identity and the like under root-example or workload-prd without re-authenticating.

# Log in once via sandbox-example
aws sso login --profile sandbox-example

# Other profiles sharing the same sso-session work right away
aws sts get-caller-identity --profile root-example
aws sts get-caller-identity --profile workload-prd

That said, this only holds when the logged-in user actually has permissions for the target account and role. A profile without an assigned permission set in Identity Center will be rejected with a permission error, even if it shares the sso-session.

When You Don’t Want to Pass —profile Every Time

If appending --profile to every command is tedious, use the AWS_PROFILE environment variable.

export AWS_PROFILE=sandbox-example

aws sts get-caller-identity
aws s3 ls
aws ec2 describe-instances

Think of this as declaring “use this profile for the rest of this shell session.” It’s handy when you want to focus on one account rather than hopping back and forth.

You can also log in by specifying an sso-session name instead of a profile.

aws sso login --sso-session example-operator

The downside is that “which account / role am I targeting?” becomes implicit, so --profile is generally clearer. Treat --sso-session as something you use during the very first setup before any profile exists, or when you specifically want to warm up multiple profiles at once.

Notes on the Legacy Format

In slightly older configurations, you may see sso_start_url and sso_region written directly inside a profile.

[profile workload-stg]
sso_start_url = https://identitycenter.amazonaws.com/ssoins-xxxxxxxxxxxxxxxx
sso_region = ap-northeast-1
sso_account_id = 444444444444
sso_role_name = AdministratorAccess

This is a leftover from pre-v2.9 AWS CLI — the so-called legacy format. It still works, but migrating to the sso-session format makes managing shared settings across multiple profiles dramatically easier. After rewriting, it looks like this.

[profile workload-stg]
sso_session = example-operator
sso_account_id = 444444444444
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

Note that the legacy format is more than just an old style — its SSO cache structure and refresh behavior are also different from the new format. If you display “SSO session: N minutes left” in your shell prompt, the display can break after migration in surprising ways (I covered that in a separate post: The Story of My SSO Session Time Dropping to 59 Minutes After Migrating to the New AWS SSO CLI Format).

Cheat Sheet of Commonly Used Commands

Finally, just the commands you’ll actually use day-to-day.

# Initial setup (interactive wizard)
aws configure sso

# SSO login by profile
aws sso login --profile sandbox-example

# Check login state
aws sts get-caller-identity --profile sandbox-example

# Pin the profile via env var
export AWS_PROFILE=sandbox-example
aws sts get-caller-identity

# Log in by sso-session name directly
aws sso login --sso-session example-operator

Conclusion

AWS CLI SSO configuration becomes much clearer once you split it into two layers: sso-session and profile.

  • [sso-session ...] holds the shared settings for the SSO login target (IAM Identity Center)
  • [profile ...] holds the AWS-account-and-role pairing
  • For initial setup, leave it to the aws configure sso interactive wizard
  • For additional profiles, copy an existing block and swap only sso_account_id and the profile name
  • Day-to-day, aws sso login --profile <name> and aws sts get-caller-identity --profile <name> are all you need
  • Profiles sharing the same sso-session are activated together by a single login
  • The legacy format (with sso_start_url written directly in a profile) is best migrated to the sso-session format

So if you want to use the sandbox-example profile, the practical bottom line is just running this one line.

aws sso login --profile sandbox-example

That’s all.