AWS Identity

AWS IAM Identity Center (SSO): Permission Sets, Account Assignments & CLI Access

Quick take: In a multi-account AWS estate, humans should never hold long-lived IAM users or access keys. IAM Identity Center is how you give every engineer one login, short-lived credentials, and exactly the right role in exactly the right accounts — from a browser or from aws sso login.

A twelve-account AWS org had thirty engineers, and every one of them carried an IAM user with an access key in a ~/.aws/credentials file. Rotating keys was a quarterly fire drill nobody finished. Onboarding meant hand-copying eleven inline policies. Off-boarding meant hoping someone remembered to delete users in all twelve accounts — and one contractor still had AdministratorAccess in the shared services account four months after the engagement ended. None of this was a policy problem. It was an identity plumbing problem, and the fix is AWS IAM Identity Center (the service formerly called AWS SSO): one place where a human signs in, one place where you say “this group gets this role in these accounts,” and short-lived credentials minted on demand instead of static keys sitting on laptops.

IAM Identity Center is not a single feature you toggle — it is a small system with distinct moving parts, and the “why can’t I see any roles?” and far more dangerous “why can this contractor still get in?” incidents come from not holding the whole chain in your head. The chain is: an identity source decides where users and groups come from (a built-in directory, Active Directory, or an external IdP like Okta or Entra ID). A permission set is a reusable bundle of policies plus a session duration — a role template. An account assignment is the triple that actually grants access: principal × permission set × account. When you assign, Identity Center provisions the permission set as a real IAM role — named AWSReservedSSO_<name>_<hash> — into each target account. The human then opens the access portal or runs aws sso login, picks an account and role, and STS hands back temporary credentials.

By the end of this article you will enable Identity Center on top of an organization, choose the right identity source, build a permission set with AWS-managed, inline, customer-managed and boundary policies, tune its session duration and relay state, assign a group to an account, log in from the portal and the CLI, wire ABAC with session tags, and auto-provision workforce from Okta/Entra over SCIM. We use real service names, real limits, real error strings, and the exact aws CLI, Terraform aws_ssoadmin_* resources and ~/.aws/config blocks — not a simplified cartoon of them. This is the modern default for human access on AWS, and it is the single highest-leverage identity investment you will make.

What problem this solves

A multi-account AWS estate that authenticates humans with IAM users has a structural flaw: identity is duplicated per account and static. Every account needs its own copy of every user, every user carries a long-lived password and access key, and there is no single lever to grant, change, or revoke access across the estate. The result is credential sprawl (keys on laptops, in repos, in CI), off-boarding gaps (a user deleted in one account but not the other eleven), and audit blindness (you cannot answer “who can touch production?” because the answer is scattered across twelve IAM databases).

What breaks without Identity Center, concretely: onboarding is O(accounts) — a new hire needs a user and policies created in every account they touch. Rotation never finishes — static access keys must be rotated on a schedule and nobody does it reliably, so 400-day-old keys become the norm. Off-boarding is best-effort — deleting a human means deleting them everywhere, and the one you miss is the breach. There is no MFA story that scales — you configure MFA per IAM user per account. And temporary access is impossible — an IAM user’s key works until you delete it; there is no natural expiry.

Who hits this: every team past a single account or past a handful of people. It bites hardest on regulated workloads (an auditor will ask you to prove least privilege and prompt off-boarding), on teams onboarding contractors and third parties, and on anyone already running AWS Organizations and IAM Foundations: Accounts, OUs and Roles who is still logging humans in with per-account IAM users. Identity Center replaces that with centralized human identity + short-lived, role-based access — and the rest of this article is how each piece works and the exact ways each one fails.

To frame the whole field before the deep sections, here is every moving part, the question it answers, and where it lives:

Layer The question it answers Where it lives Primary failure if you get it wrong
Organization What accounts exist to grant into? Management account Identity Center needs Organizations first
Identity Center instance Where do humans sign in? One home Region Wrong Region = portal 404, CLI errors
Identity source Where do users/groups come from? The instance Wrong source = “no users”, SCIM gaps
Users & groups Who is the principal? Identity store / IdP Assigning users not groups = sprawl
Permission set What can the principal do? The instance Edit without re-provision = stale access
Account assignment Where does the grant apply? Per target account Missing triple = “no roles” in portal
AWSReservedSSO role How is it enforced in-account? Each target account Manual edits get reverted on re-provision
Access portal / CLI How does the human get credentials? awsapps.com/start Region/expiry errors on aws sso login

Learning objectives

By the end of this article you can:

Prerequisites & where this fits

You should already have an AWS Organization with all features enabled (Identity Center requires it), management-account access to enable the service, and a comfort level with the aws CLI v2, JSON policy documents, and the idea that an IAM role is assumed to get temporary credentials rather than logged into. Knowing the IAM policy-evaluation order (explicit Deny wins; an SCP caps the maximum) makes the permission-set material land — if that is fuzzy, read AWS Organizations and IAM Foundations: Accounts, OUs and Roles first.

This sits in the identity and governance layer of an AWS estate. Identity Center is what a landing zone wires up for you: AWS Control Tower Guardrails: Building a Secure Multi-Account Foundation enables Identity Center as part of the baseline and expects you to manage permission sets on top of it. The guardrails that cap what any permission set can do — even an admin one — are service control policies, covered in AWS Organizations SCPs: Multi-Account Guardrails; a permission set can grant AdministratorAccess, but an SCP on the OU still wins. And where Identity Center is human access, machine and cross-account access uses role assumption directly — AWS IAM Cross-Account Roles and AssumeRole: Hands-On is the companion for that path. Identity Center is, under the hood, standardized cross-account AssumeRole for humans.

Core concepts

The mental model is a pipeline: identity source → Identity Center instance → permission set → account assignment → provisioned IAM role → temporary credentials. Get every noun in that sentence precise and the whole service becomes legible. Identity Center owns exactly two kinds of thing — who (users and groups, from your identity source) and what/where (permission sets and their assignments to accounts). It does not run workloads, hold data, or cost money by itself; it is a control plane that ends by creating IAM roles other accounts already understand.

Here is every object you will touch, what it is, and where it is defined:

Object What it is Scope Created / owned in Analogy
Instance Your Identity Center deployment One per org, one home Region Management (or delegated admin) The SSO control plane
Identity source Where users/groups originate Instance-wide (one at a time) Instance settings The address book
Identity store Built-in user/group directory The instance Identity Center Local directory (d-xxxx)
User A human principal Identity store or IdP Identity source The person
Group A set of users Identity store or IdP Identity source The team
Permission set Reusable policy bundle + session Instance-wide Instance A role template
Account assignment principal × set × account Per account Instance The actual grant
Provisioned role AWSReservedSSO_* IAM role One target account Target account The enforced permission
Access portal Web UI listing account+role tiles Per user awsapps.com/start The front door
Permissions boundary Max-permission cap on the set’s role Per permission set Instance The ceiling

And here is the lifecycle — the order things happen, and what triggers the next step. Missing any one of these is a distinct failure mode you will meet in the troubleshooting section:

# Step Trigger Result If skipped
1 Enable instance You enable Identity Center on the org Identity store d-xxxx, portal URL Nothing to sign in to
2 Set identity source Choose directory / AD / external IdP Users & groups appear No principals to assign
3 Create users/groups Manual, AD sync, or SCIM Principals exist “No users” when assigning
4 Create permission set Define policies + session duration A role template exists Nothing to assign
5 Assign to account principal × set × account Provision job runs “No roles” in portal
6 Provision Automatic on assign; manual on edit AWSReservedSSO_* role created Stale access after edits
7 Sign in Portal or aws sso login STS temp credentials

A last framing point that trips people: a permission set is not a role, and an assignment is not access until it provisions. The permission set is a template held centrally; the moment you assign it to an account, Identity Center provisions it — creates an IAM role in that account whose name starts with AWSReservedSSO_ and whose trust policy allows the Identity Center service to assume it on the user’s behalf. Edit the permission set later and the accounts do not auto-update; you must re-provision. This single fact is the root cause of a large share of “I changed the policy but access didn’t change” tickets.

IAM Identity Center vs long-lived IAM users

The core decision is simple once stated: humans get Identity Center; machines and break-glass get IAM. An IAM user is a static identity with a password and up to two access keys that live until you delete them. Identity Center gives the same human a single federated sign-in and temporary credentials scoped to a role and an account, expiring in 1–12 hours. Everything about operating at scale — onboarding, rotation, off-boarding, MFA, audit — is easier on the Identity Center side because identity is centralized and credentials are ephemeral.

Dimension Long-lived IAM users IAM Identity Center
Credential lifetime Until deleted (static) 1–12 h, minted on demand
Where identity lives Per account, duplicated Central identity store / IdP
Onboarding cost O(accounts): user + policies each Add to a group once
Off-boarding Delete in every account (miss = breach) Remove from group once
MFA Per user, per account Enforced centrally
Access keys on laptops Normal, and dangerous None — creds are temporary
Rotation Manual, scheduled, often skipped No static keys to rotate
Cross-account Duplicate users or set up roles Native: assign set to N accounts
Audit “who can touch prod?” Scattered across accounts One assignments view
Console + CLI parity Yes Yes (portal + aws sso login)
External IdP integration SAML per account, painful SAML + SCIM, centrally
Cost Free Free (unless you run AD)
Right for Break-glass, some automation All human access

You do not delete IAM entirely — you demote it. A handful of roles remain the correct tool, and a break-glass IAM user with a physical MFA key is a deliberate safety net for the day Identity Center or your IdP is unavailable.

Keep an IAM identity for… Why Guardrail
Break-glass user Recover if IdP/Identity Center is down Physical MFA, sealed password, alarmed on use
Automation / CI roles Machines assume roles, not portals OIDC / instance roles, no static keys
Service-linked roles AWS services need them Managed by AWS
Legacy third-party Vendor only supports IAM keys Scope tightly, rotate, prefer roles
EC2 / Lambda execution Workload identity Instance profile / execution role
Root user Account-level tasks only MFA, never for daily work

The punchline for exams and for real life: if a person is typing, they should be coming through Identity Center. If code is calling, it should be assuming a role. Static IAM access keys for humans are a finding, not a design.

Choosing an identity source

An Identity Center instance has exactly one identity source at a time, and it is the biggest early decision because switching it later is disruptive. The source determines where users and groups come from and how they authenticate. There are three families, with Active Directory offering two connection styles.

Identity source Auth handled by Provisioning Best for Cost
Identity Center directory Identity Center (built-in) Manual / SCIM Small teams, no existing IdP Free
AWS Managed Microsoft AD Your managed AD AD sync AD-centric shops, on-AWS AD ~$0.40/hr (Standard)
AD Connector Your on-prem AD AD sync Existing on-prem AD, no new DCs ~$0.05/hr (small)
External IdP (SAML+SCIM) Okta / Entra / Ping / etc. SCIM 2.0 Orgs standardized on an IdP IdP licensing

The built-in Identity Center directory (the identity store, identified as d-xxxxxxxxxx) is the zero-dependency default: you create users and groups directly, Identity Center handles passwords and MFA, and there is nothing else to run. It is the fastest path for a lab or a small org, and you can still bulk-load it over SCIM.

Choosing Active Directory means users authenticate against your directory. AWS Managed Microsoft AD runs actual domain controllers in AWS (a real, billed resource); AD Connector is a lightweight proxy to your on-prem AD (cheaper, no DCs in AWS, but auth latency depends on the link). Both surface AD users/groups into Identity Center via directory sync.

Choosing an external IdP splits the job cleanly into two protocols, and understanding the split is the difference between a smooth rollout and a week of “the user exists in Okta but not in AWS” tickets:

Concern Protocol Direction What it does Failure if misconfigured
Sign-in / authentication SAML 2.0 IdP → Identity Center Proves who the user is at login Can’t log in; SAML assertion errors
User/group provisioning SCIM 2.0 IdP → Identity Center Pushes users/groups into the store User can log in but has no groups/roles
Attributes for ABAC SAML attrs / SCIM IdP → session tags Carries department, project, etc. PrincipalTag conditions never match
Deprovisioning SCIM IdP → Identity Center Removes/disables leavers Off-boarding gap
Group membership SCIM IdP → Identity Center Keeps groups in sync Assignments target empty groups

SAML is only about sign-in; SCIM is what actually creates the users and groups inside Identity Center so you have something to assign. Enable one without the other and you get the classic symptom: the user authenticates fine but the access portal shows no accounts and no roles, because the identity carries no group that any assignment references.

External IdP specifics differ enough between the two dominant providers to warrant a side-by-side:

Aspect Okta Microsoft Entra ID (Azure AD)
App to add “AWS IAM Identity Center” app “AWS IAM Identity Center” enterprise app
SAML metadata Exchange metadata XML both ways Exchange metadata XML both ways
SCIM endpoint From Identity Center settings From Identity Center settings
SCIM token Bearer token from Identity Center Bearer token from Identity Center
What syncs Assigned users + pushed groups Assigned users + groups in scope
Group sync gotcha Must “push groups” explicitly Only groups assigned to the app sync
Attribute for ABAC Okta profile → SAML attribute Entra claim → SAML attribute
Nested groups Flattened on push Not expanded — assign leaf groups

The single most common external-IdP mistake, in both tools: assuming that all IdP groups appear in AWS. They do not. Only the users assigned to the AWS app and the groups you explicitly scope/push are provisioned over SCIM. An assignment that targets a group the IdP never pushed grants nothing.

Finally, switching identity source is not a casual toggle. Changing the source can remove existing assignments and always resets MFA registrations, because principal IDs are recreated. Plan it as a migration:

If you change from… To… What happens Do this first
Identity Center dir External IdP Users recreated via SCIM; assignments may drop Export assignments; re-map by group
Identity Center dir Active Directory Directory-sourced users; local users removed Recreate groups in AD
Active Directory External IdP Re-provision from IdP; principal IDs change Re-create assignments post-cutover
External IdP Identity Center dir SCIM stops; users become local Rebuild groups/memberships
Any change Any MFA devices reset; users re-enroll Warn users; schedule a window

The safe pattern is to pick your long-term source before you build permission sets and assignments, especially if you already run Okta or Entra. Retrofitting an IdP after 200 assignments exist means re-doing those assignments against new principal IDs.

Permission sets in depth

A permission set is the heart of the service: a named, reusable bundle of permissions plus session behaviour that you assign to any number of accounts, where it becomes an IAM role. Think of it as the job — “Platform Admin,” “Read-Only Auditor,” “Billing Viewer” — decoupled from which account and which person. You define it once, centrally, and assign it wherever that job applies.

A permission set is built from up to five permission components plus two behaviour settings:

Component What it is How many Materializes as When to use
AWS managed policies AWS-authored policies (e.g. ReadOnlyAccess) Multiple Attached managed policies on the role Fast, standard job profiles
Inline policy One JSON policy embedded in the set One Inline policy on the role Set-specific grants/denies
Customer-managed policies Referenced by name, must exist in each account Multiple Attached managed policies on the role Reused policies you version yourself
Permissions boundary Max-permission ceiling for the role One Boundary on the role Cap delegated admins
Session duration How long the role session lasts One (PT1H–PT12H) MaxSessionDuration on the role Longer for interactive admins
Relay state Post-login redirect URL One Console landing page Deep-link to a service/region

Two of these have sharp edges. AWS-managed vs customer-managed policies: an AWS-managed policy is referenced by a single global ARN and always exists. A customer-managed policy reference is attached by name and path, and the actual policy must already exist in every target account — Identity Center does not copy it there. Assign a set that references arn:aws:iam::<acct>:policy/MyOrgBaseline to an account that lacks that policy and provisioning fails. This is powerful (you version the policy yourself, per account, e.g. via AWS Control Tower Guardrails: Building a Secure Multi-Account Foundation or Terraform) and a common footgun.

Policy type in a set Where the policy lives Same across accounts? Failure mode
AWS managed AWS global (arn:aws:iam::aws:policy/…) Yes, always Rare
Inline Inside the permission set Yes (copied on provision) Size limit exceeded
Customer-managed (referenced) Each target account, by name Only if you deploy it everywhere Missing in an account → provision fails
Permissions boundary AWS managed or customer-managed Depends on which Boundary missing → provision fails

Session duration

Session duration controls how long the temporary credentials from this permission set last before the user must re-authenticate the role (distinct from the portal sign-in session). It is an ISO-8601 duration from PT1H to PT12H. Longer is more convenient for interactive admins; shorter shrinks the window a leaked credential is usable.

Setting Value range Default When to lengthen When to shorten
Session duration PT1H – PT12H PT1H Long interactive admin work Sensitive/prod access
Common admin PT4H – PT8H Full workday without re-login
Common read-only PT8H – PT12H Dashboards, monitoring
Sensitive/prod PT1H Minimize blast radius
Break-glass emulation PT1H Force frequent re-auth

There are two different session clocks and confusing them causes “why did I get logged out?” tickets. The permission-set session duration (PT1H–PT12H) is how long a set of role credentials lasts. The access-portal (sign-in) session is a separate, instance-wide setting — default 8 hours, configurable roughly 15 minutes to 90 days — controlling how long before the user must re-authenticate to the portal itself.

Session type Governs Range Default Set where
Permission-set session Role credential lifetime PT1H–PT12H PT1H Per permission set
Access-portal session Portal re-authentication ~15 min – 90 days 8 h Instance settings
AWS console session (via portal) Console tab validity Follows role session Derived

Relay state

Relay state is a small quality-of-life setting: a URL the console redirects to immediately after federated login through this permission set. Point an operations set at the CloudWatch console in your primary Region and admins land where they work instead of the generic console home. It has no security effect; it is pure ergonomics.

https://ap-south-1.console.aws.amazon.com/cloudwatch/home?region=ap-south-1

Provisioning and the AWSReservedSSO role

When you assign a permission set to an account (or edit an already-assigned one and re-provision), Identity Center creates or updates an IAM role in that account. Knowing its shape is essential for debugging and for writing trust policies elsewhere that reference it.

Property Value / behaviour Why it matters
Role name AWSReservedSSO_<PermSetName>_<16-hex-hash> Predictable prefix; hash differs per account
Path /aws-reserved/sso.amazonaws.com/ Filter SSO roles by path
Trust policy Trusts the Identity Center SAML provider Do not edit — reverted on re-provision
Managed edits Reverted on next provision Never hand-edit these roles
Session name The user’s Identity Center username Shows in CloudTrail as the human
Deletion Removed when the last assignment is removed Un-assign to clean up
Boundary Present if the set has one Enforced as the ceiling

Because the role name embeds a per-account random hash, never hardcode the full name across accounts; match on the AWSReservedSSO_ prefix or the reserved path when you need to reference these roles (for example in a resource policy that must allow “any SSO admin”). CloudTrail records the human’s username as the role session name, so an SSO-driven action is attributable to a person, not to an anonymous shared role — a major audit win over shared IAM users.

The provisioning lifecycle has explicit states, and reading them is how you confirm an edit actually took effect:

Provisioning state Meaning Your action
IN_PROGRESS Provision job running Wait, then re-check
SUCCEEDED Role created/updated in account Done
FAILED Missing dependency (e.g. referenced policy) Read the failure reason, fix, re-provision
Out of date (implicit) Set edited, accounts not re-provisioned Run provision-permission-set

Limits and quotas

Enumerate the ceilings before you design, because several are low and shape your permission-set strategy (favour fewer, broader sets over hundreds of narrow ones). Quotas can change and some are adjustable via Service Quotas — verify current values, but these are the orders of magnitude:

Limit Approx. value Adjustable? Design implication
Permission sets per instance 500 Some limits adjustable Don’t create one per person
Permission sets provisioned per account 50 Check quotas Reuse sets across accounts
AWS managed policies per set ~10–20 Follows IAM role limit Consolidate policies
Inline policy size per set ~10,240 chars No Prefer managed refs for big policies
Customer-managed refs per set Multiple (with limits) Check quotas Policy must exist in each account
Accounts per assignment API call One (AWS_ACCOUNT) Loop or use IaC for many accounts
Session duration PT1H–PT12H No Can’t exceed 12 h
Identity source 1 per instance No Choose carefully upfront
Instance 1 org instance Account instances possible Prefer the org instance
AWSReservedSSO roles Count toward IAM roles/account (~1,000) IAM quota adjustable Many sets × many accounts adds up

Account assignments: principal × permission set × account

An account assignment is what actually grants access, and it is a triple: a principal (a group or user), a permission set, and a target account. All three must be present and the assignment must be provisioned for a human to see a role tile in the portal. Miss any leg of the triple and the user gets nothing — this is the single most common “it’s not working” cause, and it is almost always a missing or mis-targeted assignment rather than a policy problem.

Leg of the triple What it is Choose Anti-pattern
Principal Who gets access A group (ideally) Assigning individual users
Permission set What they can do The job template One set per person
Target account Where it applies A specific account ID Expecting OU-wide magic

Always assign groups, not users. A group assignment means onboarding is “add to the group” and off-boarding is “remove from the group” — zero AWS changes. Assigning individual users recreates the per-account sprawl Identity Center exists to kill.

Assign to… Onboarding Off-boarding Scales?
Group Add user to group Remove from group Yes
Individual user New assignment per account Delete assignment per account No — sprawl returns

A frequent misconception: there is no OU-level assignment. You assign a permission set to accounts, one account per assignment. To grant a group ReadOnly across an OU of 20 accounts, you create 20 assignments — which is exactly why you drive assignments from Terraform or a loop, not the console, at scale.

Operation API / CLI Terraform Notes
Create assignment sso-admin create-account-assignment aws_ssoadmin_account_assignment Auto-provisions on create
Delete assignment sso-admin delete-account-assignment Destroy the resource Removes role if last one
List assignments sso-admin list-account-assignments Data source Per account + set
Provision (re-sync) sso-admin provision-permission-set Implicit on change Needed after set edits
List accounts for a set sso-admin list-accounts-for-provisioned-permission-set Audit which accounts have it

The access portal and CLI: aws sso login

Once a user is assigned, they consume access two ways. The access portalhttps://d-xxxxxxxxxx.awsapps.com/start or a custom subdomain — is a web page of tiles, one per account+permission-set they are entitled to, each offering “Management console” or “Command line access.” The CLI path is aws sso login, and the modern (AWS CLI v2 ≥ 2.9) way to configure it uses a token-based [sso-session] block shared across profiles.

The three ways to reach a role, and when to use each:

Method How Best for Credential lifetime
Access portal (console) Click “Management console” Interactive console work Portal/role session
Access portal (copy creds) Click “Command line access”, copy One-off CLI on a shared box Role session
aws sso login (CLI) Configured profile + browser device flow Daily CLI/SDK/IaC work Role session, auto-cached

Configure it once with aws configure sso, which writes both blocks to ~/.aws/config:

aws configure sso --profile dev-admin
# SSO session name: my-org
# SSO start URL: https://d-1234567890.awsapps.com/start
# SSO region: ap-south-1
# SSO registration scopes: sso:account:access
# → it lists your accounts/roles; pick one

The resulting file — the [sso-session] block is reusable across every profile so you authenticate once and get all your accounts:

[sso-session my-org]
sso_start_url = https://d-1234567890.awsapps.com/start
sso_region = ap-south-1
sso_registration_scopes = sso:account:access

[profile dev-admin]
sso_session = my-org
sso_account_id = 111122223333
sso_role_name = AdminAccess
region = ap-south-1
output = json

[profile prod-readonly]
sso_session = my-org
sso_account_id = 444455556666
sso_role_name = ReadOnly
region = ap-south-1
output = json

Every field, what it does, and the failure if it is wrong:

Field Block Meaning If wrong
sso_start_url sso-session Your portal URL Login can’t find the instance
sso_region sso-session The instance home Region Token/login errors
sso_registration_scopes sso-session OIDC scope (sso:account:access) Registration fails
sso_session profile Links profile → session block Falls back to legacy format
sso_account_id profile Target account (12 digits) “role not available in account”
sso_role_name profile Permission set name (not ARN) Role not found
region profile Default Region for API calls Calls hit wrong Region
output profile CLI output format Cosmetic

Then the daily flow:

aws sso login --sso-session my-org      # opens browser; approve the device code
aws sts get-caller-identity --profile dev-admin
# → Arn: arn:aws:sts::111122223333:assumed-role/AWSReservedSSO_AdminAccess_abc123.../jdoe
aws s3 ls --profile dev-admin           # real command with temp creds
aws sso logout                          # clears the cached token

Under the hood, aws sso login runs an OAuth 2.0 device authorization flow: the CLI registers a client, opens your browser to the portal, you approve, and an SSO access token is cached in ~/.aws/sso/cache/. Individual role credentials are then fetched on demand and cached in ~/.aws/cli/cache/. The token — not your role creds — is what expires and forces the next aws sso login.

Cache / artifact Location Contains Lifetime
SSO access token ~/.aws/sso/cache/*.json Portal OIDC token Portal session
Role credentials ~/.aws/cli/cache/*.json Temp STS creds Role session (PT1H–PT12H)
Client registration ~/.aws/sso/cache/ OIDC client reg ~90 days
Config ~/.aws/config sso-session + profiles Until you edit

The admin/automation CLIs you use to build Identity Center are separate from the aws sso used to consume it. Know the three services:

CLI namespace Purpose Key commands
aws sso-admin Manage sets & assignments create-permission-set, attach-managed-policy-to-permission-set, put-inline-policy-to-permission-set, create-account-assignment, provision-permission-set, describe-permission-set
aws identitystore Manage users & groups create-user, create-group, create-group-membership, list-users, list-groups
aws sso Consume access (login) login, logout, list-accounts, list-account-roles

ABAC, session tags and SCIM auto-provisioning

Two advanced capabilities take Identity Center from “central login” to “policy that writes itself.” Attribute-based access control (ABAC) lets one permission set serve many teams by scoping access with attributes carried from your identity source. SCIM keeps your workforce in sync automatically so you never touch users by hand.

ABAC with session tags

Enable attributes for access control on the instance, and selected user attributes (from the identity store, SAML assertions, or SCIM) are attached to the role session as session tags. Your permission-set policy then uses aws:PrincipalTag/<key> conditions, so a single DeveloperAccess set can restrict each user to resources tagged with their department or project — no per-team set required.

ABAC piece What it is Example
Source attribute Field on the user in your IdP/store department = payments
Attribute mapping Maps source → Identity Center attribute ${path:enterprise.department}
Session tag Attribute on the assumed-role session aws:PrincipalTag/Department
Policy condition Uses the tag to allow/deny StringEquals: {aws:PrincipalTag/Department: payments}
Resource tag Tag on the AWS resource Department = payments
Match Session tag == resource tag → allow Access granted only to own dept
Enable at Instance → “attributes for access control” Required first

A policy fragment inside a permission set that scopes EC2 control to the user’s own department:

{
  "Effect": "Allow",
  "Action": ["ec2:StartInstances", "ec2:StopInstances"],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:ResourceTag/Department": "${aws:PrincipalTag/Department}"
    }
  }
}

The single ABAC failure to internalize: if the attribute is not populated and mapped, the session tag is absent, aws:PrincipalTag/Department resolves to nothing, and the condition silently never matches — the user is denied everywhere and it looks like a policy bug. Confirm the attribute lands with aws sts get-caller-identity context and CloudTrail, not by staring at the policy.

SCIM auto-provisioning

SCIM 2.0 (System for Cross-domain Identity Management) is the protocol by which your external IdP pushes users and groups into Identity Center and keeps them current — creating joiners, updating changes, and deprovisioning leavers. You enable automatic provisioning in Identity Center, which hands you a SCIM endpoint URL and a bearer token, and you paste both into the IdP’s provisioning config.

SCIM behaviour What happens Watch out for
Create New IdP user → new Identity Center user Only assigned users sync
Update Attribute change → synced Mapping must include the attribute
Deactivate Leaver disabled in IdP → disabled in AWS Confirms off-boarding
Group push Assigned group → Identity Center group Must be explicitly pushed/scoped
Nested groups Not expanded Assign leaf groups
Token expiry SCIM bearer token expires (~1 year) Rotate before expiry or sync stops
Sync cadence Periodic (IdP-driven, ~40 min typical) Not instant; allow lag

The two SCIM failures you will meet: a group that was never pushed (so an assignment against it grants nothing — the fix is to scope/push that group in the IdP), and an expired SCIM token (so sync silently stops and new hires never appear — the fix is to rotate the token in Identity Center and update the IdP). Neither throws an obvious error in the AWS console; both show up as “the user/group isn’t in Identity Center.”

Architecture at a glance

Read the diagram left to right — it is the authorization and access path, not a request packet. On the far left a workforce user lives in an external IdP (Okta or Entra ID); SAML 2.0 authenticates them and SCIM 2.0 provisions them into IAM Identity Center, which runs in a single home Region and owns the identity store and MFA. In the centre, permission sets are reusable role templates — one carries AdministratorAccess with a PT1H session, another ReadOnly with a boundary. The organization ties accounts into OUs, and an account assignment — the group × set × account triple — provisions each set into its target accounts, where it materializes as an AWSReservedSSO_* IAM role. Finally the user opens the access portal or runs aws sso login, picks an account and role, and STS returns temporary credentials valid up to 12 hours.

Each numbered badge marks a real place where access is silently denied or over-granted: SAML/SCIM mapping at the IdP (1), the one-Region/one-source constraint of the instance (2), re-provisioning after editing a set (3), the assignment triple that is so often incomplete (4), the role and its ABAC session tags materializing in-account (5), and the CLI login where Region and token-expiry errors bite (6). The legend narrates each as symptom, how to confirm, and fix.

IAM Identity Center access path: a workforce user in an external IdP federates via SAML and SCIM into IAM Identity Center in one home Region, permission sets (AdminAccess PT1H, ReadOnly with boundary) are assigned as the principal-times-set-times-account triple across an organization's Prod, Dev and Security OUs, provision into each target account as AWSReservedSSO IAM roles, and the user obtains temporary credentials through the access portal or aws sso login; six numbered badges mark SAML/SCIM mapping, one-region/one-source, re-provision-after-edit, the assignment triple, role materialization with ABAC tags, and CLI login region/expiry errors.

Real-world scenario

Northwind Payments, a fictional but representative fintech, ran 18 AWS accounts under Organizations with 45 engineers, and every engineer had IAM users in the 4–6 accounts they touched. The trigger for change was an audit finding: a departed contractor still held PowerUserAccess in the shared-services account 90 days after leaving, discovered only because IAM Access Analyzer flagged an access key last used the day before. The auditor’s question — “prove that no former employee retains access to production” — was unanswerable, because the answer lived in 18 separate IAM databases.

The platform team’s remediation was a two-week Identity Center rollout. They already ran Entra ID for corporate identity, so they set the identity source to external IdP, exchanged SAML metadata, and enabled SCIM so joiners, movers and leavers flowed automatically from HR-driven Entra groups. They defined seven permission sets instead of the sprawl of inline policies: PlatformAdmin (AdministratorAccess, PT1H, boundary-capped), AppDeveloper (a curated inline policy plus ABAC on Department), ReadOnlyAuditor (ReadOnlyAccess, PT12H), BillingViewer, SecurityBreakGlass, NetworkAdmin, and DBOperator. ABAC was the unlock: instead of an AppDeveloper set per squad, one set scoped every engineer to resources tagged with the department Entra pushed as a session tag, so the payments squad could never touch the lending squad’s resources despite sharing a permission set.

Assignments were driven entirely from Terraform — a map of {group, permission_set, account} triples rendered aws_ssoadmin_account_assignment resources, so granting ReadOnlyAuditor across the seven-account “Prod” OU was seven lines of HCL, code-reviewed and version-controlled. The PlatformAdmin set carried a permissions boundary so that even an admin could not disable CloudTrail or leave the organization — the guardrail held above the role, complementing the SCPs on the OUs (see AWS Organizations SCPs: Multi-Account Guardrails).

The results were concrete. Onboarding a new engineer dropped from “raise tickets for IAM users in six accounts” to “HR adds them to an Entra group; SCIM syncs them in ~40 minutes.” Off-boarding became instant and provable: disable in Entra, SCIM deactivates them everywhere, and the audit answer is a single assignments export plus CloudTrail. One incident surfaced during rollout — engineers reported “no accounts in the portal” on day one. Root cause: the Entra groups had been created but not pushed to the AWS SCIM app, so the assignments referenced empty groups. Scoping the groups to the app fixed it in minutes and became the top item on their runbook. Six months on, there is not a single human IAM access key left in the org, and the mean time to off-board went from “days, best-effort” to “minutes, guaranteed.”

Advantages and disadvantages

Advantages Disadvantages / costs
One login for a human across all accounts Requires AWS Organizations (all features)
Temporary credentials — no static keys to leak One identity source per instance (lock-in-ish)
Onboarding/off-boarding via group membership Switching source is disruptive (re-map, MFA reset)
Centralized MFA enforcement Permission-set edits need explicit re-provision
Attributable actions (human name in CloudTrail) No OU-level assignment — per-account grants
ABAC: one set scopes many teams ABAC misconfig fails silently (empty session tag)
Free service AD source (Managed AD) is billed
Native Terraform (aws_ssoadmin_*) support Customer-managed policy must exist in each account
Console + CLI + SDK parity (aws sso login) Single home Region — get it right upfront
1–12 h session tuning per set Portal vs role session confusion for users

Where each matters: the temporary-credentials and off-boarding advantages are decisive for any regulated or growing org — they turn the two hardest identity problems into group edits. The disadvantages are mostly upfront design costs (pick the source and Region carefully, deploy customer-managed policies everywhere, wire re-provisioning into your pipeline) rather than ongoing pain. The one that bites operationally forever is re-provision-after-edit: bake it into your IaC/CI so a changed set always re-syncs to its accounts.

Hands-on lab

This lab enables Identity Center, creates a group and user in the built-in directory, builds a ReadOnly permission set, assigns it to one account, and logs in via aws sso login. It is free (the Identity Center directory costs nothing; you run no AD). Do it in the management account of a test organization, or a delegated admin account.

⚠️ Cost note: IAM Identity Center and its built-in directory are free. This lab incurs no charges. If you instead choose AWS Managed Microsoft AD as a source, that directory is billed (~$0.40/hr). Teardown at the end removes the assignment and permission set.

Step 1 — Enable Identity Center and capture identifiers

Console: IAM Identity Center → Enable. Choose your home Region deliberately (you cannot easily move it). Then capture the instance ARN and identity store ID:

aws sso-admin list-instances
# {
#   "Instances": [{
#     "InstanceArn": "arn:aws:sso:::instance/ssoins-abc1234567890def",
#     "IdentityStoreId": "d-1234567890"
#   }]
# }
INSTANCE_ARN=arn:aws:sso:::instance/ssoins-abc1234567890def
STORE_ID=d-1234567890

Expected: one instance ARN and a d-xxxxxxxxxx identity store ID. Note your portal URL from the console dashboard (e.g. https://d-1234567890.awsapps.com/start).

Step 2 — Create a group and user (built-in directory)

GROUP_ID=$(aws identitystore create-group \
  --identity-store-id "$STORE_ID" \
  --display-name "ReadOnly-Auditors" \
  --query GroupId --output text)

USER_ID=$(aws identitystore create-user \
  --identity-store-id "$STORE_ID" \
  --user-name "jdoe" \
  --display-name "Jane Doe" \
  --name Formatted="Jane Doe",FamilyName="Doe",GivenName="Jane" \
  --emails Value="jane@example.com",Type="work",Primary=true \
  --query UserId --output text)

aws identitystore create-group-membership \
  --identity-store-id "$STORE_ID" \
  --group-id "$GROUP_ID" \
  --member-id UserId="$USER_ID"

Expected: a GroupId, a UserId, and a membership. In the console the user appears under Users; they will receive an email to set a password and register MFA (or you set it manually).

Step 3 — Create the permission set

PS_ARN=$(aws sso-admin create-permission-set \
  --instance-arn "$INSTANCE_ARN" \
  --name "ReadOnly" \
  --description "Org-wide read-only auditor access" \
  --session-duration "PT8H" \
  --relay-state "https://ap-south-1.console.aws.amazon.com/cloudwatch/home?region=ap-south-1" \
  --query PermissionSet.PermissionSetArn --output text)

aws sso-admin attach-managed-policy-to-permission-set \
  --instance-arn "$INSTANCE_ARN" \
  --permission-set-arn "$PS_ARN" \
  --managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"

Expected: a permission-set ARN like arn:aws:sso:::permissionSet/ssoins-.../ps-abc123..., with ReadOnlyAccess attached.

Step 4 — Assign the group to an account

TARGET_ACCOUNT=111122223333   # a member account ID

aws sso-admin create-account-assignment \
  --instance-arn "$INSTANCE_ARN" \
  --target-id "$TARGET_ACCOUNT" --target-type AWS_ACCOUNT \
  --permission-set-arn "$PS_ARN" \
  --principal-type GROUP --principal-id "$GROUP_ID"

This auto-provisions. Confirm the role landed in the target account:

aws sso-admin list-account-assignments \
  --instance-arn "$INSTANCE_ARN" \
  --account-id "$TARGET_ACCOUNT" \
  --permission-set-arn "$PS_ARN"
# → PrincipalType GROUP, PrincipalId <group>, PermissionSetArn <ps>

Expected: the assignment listed, and (in the target account) an IAM role named AWSReservedSSO_ReadOnly_<hash> under path /aws-reserved/sso.amazonaws.com/.

Step 5 — Configure the CLI and log in

As the assigned user (jdoe, after they set a password + MFA):

aws configure sso --profile audit
# SSO session name: my-org
# SSO start URL: https://d-1234567890.awsapps.com/start
# SSO region: ap-south-1
# scopes: sso:account:access
# → pick account 111122223333, role ReadOnly

aws sso login --sso-session my-org
aws sts get-caller-identity --profile audit
# Arn: arn:aws:sts::111122223333:assumed-role/AWSReservedSSO_ReadOnly_<hash>/jdoe
aws s3 ls --profile audit          # works (read-only)
aws s3 mb s3://should-fail --profile audit  # AccessDenied — read-only, as intended

Expected: get-caller-identity shows the assumed AWSReservedSSO_ReadOnly role with jdoe as the session name; reads succeed, writes are denied.

Verification checkpoints

Checkpoint Command / place Pass looks like
Instance exists aws sso-admin list-instances One ARN + d-xxxx
User in group Console → Groups → members jdoe listed
Set has policy aws sso-admin list-managed-policies-in-permission-set ReadOnlyAccess
Assignment exists list-account-assignments Your group + set
Role provisioned Target account IAM roles AWSReservedSSO_ReadOnly_*
Login works aws sts get-caller-identity Assumed-role ARN + username
Least privilege holds aws s3 mb (write) AccessDenied

The same in Terraform

data "aws_ssoadmin_instances" "this" {}

locals {
  instance_arn      = tolist(data.aws_ssoadmin_instances.this.arns)[0]
  identity_store_id = tolist(data.aws_ssoadmin_instances.this.identity_store_ids)[0]
}

resource "aws_identitystore_group" "auditors" {
  identity_store_id = local.identity_store_id
  display_name      = "ReadOnly-Auditors"
  description        = "Read-only auditors"
}

resource "aws_ssoadmin_permission_set" "readonly" {
  name             = "ReadOnly"
  description      = "Org-wide read-only auditor access"
  instance_arn     = local.instance_arn
  session_duration = "PT8H"
  relay_state      = "https://ap-south-1.console.aws.amazon.com/cloudwatch/home?region=ap-south-1"
}

resource "aws_ssoadmin_managed_policy_attachment" "readonly" {
  instance_arn       = local.instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.readonly.arn
  managed_policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

resource "aws_ssoadmin_account_assignment" "readonly_dev" {
  instance_arn       = local.instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.readonly.arn
  principal_id       = aws_identitystore_group.auditors.group_id
  principal_type     = "GROUP"
  target_id          = "111122223333"
  target_type        = "AWS_ACCOUNT"
}

Terraform handles re-provisioning on change automatically — editing the managed-policy attachment and re-applying pushes the update to assigned accounts, which is exactly why IaC beats the console here.

Teardown

aws sso-admin delete-account-assignment \
  --instance-arn "$INSTANCE_ARN" \
  --target-id "$TARGET_ACCOUNT" --target-type AWS_ACCOUNT \
  --permission-set-arn "$PS_ARN" \
  --principal-type GROUP --principal-id "$GROUP_ID"

aws sso-admin delete-permission-set \
  --instance-arn "$INSTANCE_ARN" --permission-set-arn "$PS_ARN"

aws identitystore delete-user  --identity-store-id "$STORE_ID" --user-id  "$USER_ID"
aws identitystore delete-group --identity-store-id "$STORE_ID" --group-id "$GROUP_ID"

Deleting the last assignment removes the AWSReservedSSO_ReadOnly_* role from the target account. You can leave the instance enabled (it is free) or disable it in the console.

Common mistakes & troubleshooting

This is the section you will return to. The playbook table first — symptom to root cause to the exact confirm to the fix — then a status/error reference and a decision table, then prose on the three nastiest failures.

# Symptom Root cause Confirm (exact command / console path) Fix
1 Portal shows no accounts / no roles No assignment references the user’s groups aws sso-admin list-account-assignments --account-id <acct> --permission-set-arn <ps> Assign the user’s group × set × account
2 Edited a permission set, access unchanged Assigned accounts not re-provisioned aws sso-admin describe-permission-set vs the role’s policies aws sso-admin provision-permission-set --target-type ALL_PROVISIONED_ACCOUNTS
3 aws sso login: Token has expired SSO access token expired aws sts get-caller-identity --profile p → SSOTokenLoadError Re-run aws sso login --sso-session <name>
4 aws sso login: browser never opens Headless / no default browser Look for the printed URL + code Open URL manually, enter the code
5 Login/token errors with wrong Region sso_region ≠ instance home Region Check portal URL Region vs ~/.aws/config Set sso_region to the home Region
6 User authenticates but has no groups SCIM group never pushed from IdP Identity Center → Groups (group absent/empty) Push/scope the group in the IdP SCIM app
7 New hires never appear in AWS SCIM bearer token expired Identity Center → provisioning status; IdP sync logs Rotate SCIM token; update the IdP
8 Provisioning FAILED on a set Referenced customer-managed policy missing in account describe-permission-set-provisioning-status reason Deploy the policy in that account, re-provision
9 ABAC condition never matches Attribute not populated/mapped → empty session tag CloudTrail session context; confirm attribute set Map ${path:...} attribute; enable ABAC attributes
10 Admin edited the AWSReservedSSO role, change vanished Re-provision reverts manual edits Compare role now vs after next provision Edit the permission set, never the role
11 External IdP: can’t sign in at all SAML metadata/trust mismatch IdP sign-in logs; SAML response error Re-exchange SAML metadata both ways
12 sso_role_name not found Used the permission-set ARN, not its name ~/.aws/config profile Set sso_role_name to the set name
13 Access works, then drops mid-task Permission-set session (PT1H) expired get-caller-identity fails after ~1 h Raise session duration or re-login
14 Can’t enable Identity Center Organizations not in all features Organizations console → settings Enable all features first

The status and error strings you will actually see, decoded:

Error / status Where Meaning Fix
SSOTokenLoadError / Token has expired CLI SSO token missing/expired aws sso login again
Error loading SSO Token CLI No cached token for the session aws sso login --sso-session <name>
UnauthorizedException sso/sso-admin Token invalid or no permission Re-login; check admin IAM perms
The SSO session has expired or is invalid CLI/SDK Portal session ended Re-authenticate
AccessDeniedException on sso-admin:* Admin CLI Caller lacks Identity Center admin Grant AWSSSODirectoryAdministrator/SSO admin
Provisioning status FAILED sso-admin Missing dependency (policy/boundary) Read reason; deploy dependency; re-provision
SAML Response was not successful IdP Assertion/trust mismatch Re-exchange metadata; check attribute map
SCIM 401 / token invalid IdP provisioning Expired/wrong SCIM token Rotate token in Identity Center
No roles available (portal) Portal User assigned to nothing Create the assignment triple
ConflictException on assign sso-admin Assignment already exists It’s already there — no action
ThrottlingException Bulk assigns Too many API calls Back off; use IaC with retries
Role MaxSessionDuration mismatch Console Set session > role cap Session set to PT1H–PT12H only

And the fast decision table for the two symptoms that account for most tickets:

If you see… It’s probably… Do this
No roles/accounts in portal Missing or mis-targeted assignment Assign the group to the account
Policy edit didn’t take effect Not re-provisioned provision-permission-set
Login worked yesterday, fails today Token expired aws sso login
User exists in IdP, not in AWS SCIM didn’t push the group Scope/push group; check SCIM token
Condition denies everyone Empty session tag (ABAC) Map + populate the attribute
Manual role edit reverted Re-provision overwrote it Edit the set, not the role
“Not authorized” running sso-admin You lack SSO admin rights Grant SSO admin; use delegated admin
Can’t enable the service Org not all-features Enable all features in Organizations

The three nastiest failures, in prose. First, “no roles in the portal” after an external-IdP rollout. The user signs in perfectly (SAML works), so it looks like an AWS problem, but the access portal is empty. The cause is almost always that the IdP created the user but never pushed the group over SCIM — Okta requires you to “push groups” explicitly and Entra only syncs groups scoped to the enterprise app. Your assignment targets a group that, from AWS’s view, has no members. Confirm in Identity Center → Groups (the group is missing or empty) and in the IdP’s provisioning logs. The fix is to scope/push the group in the IdP; do not add users individually in AWS as a workaround, because SCIM will fight you.

Second, the silent re-provision gap. You tighten a permission set — remove an action, add a Deny — apply it, and the offending access still works. Identity Center changed the template but did not touch the already-provisioned roles in the member accounts; they are now out of date. This is not a bug, it is the model: assignments do not auto-track set edits. Confirm by comparing describe-permission-set against the actual role in a target account. The fix is aws sso-admin provision-permission-set --target-type ALL_PROVISIONED_ACCOUNTS (or Terraform, which does it for you). Wire this into your pipeline so a merged set change always re-provisions — otherwise your policy-as-code drifts from reality and a security tightening never lands.

Third, ABAC that denies everyone. You build one DeveloperAccess set with a aws:PrincipalTag/Department condition, roll it out, and every developer is denied everything. The policy is correct; the session tag is empty. Either “attributes for access control” is not enabled on the instance, or the department attribute is not mapped from the IdP/store, or the IdP user simply has no department value. Because an absent tag makes the StringEquals condition false, the effect is a blanket deny that reads like a policy bug. Confirm by inspecting the assumed-role session context (CloudTrail requestParameters/session tags) — not the policy JSON. Fix the mapping (${path:enterprise.department} for AD, the SAML/SCIM attribute for an IdP) and ensure the attribute is populated for real users before you cut over.

Best practices

Security notes

Identity Center is a security control, but it has its own attack surface and least-privilege story. The core wins are structural: no long-lived human keys, centrally enforced MFA, temporary credentials, and human-attributable CloudTrail. Layer the following on top.

Control Why How
Delegated administration Keep humans out of the management account Register a security account as SSO delegated admin
MFA enforcement Stop credential-only compromise Require MFA; prefer WebAuthn/FIDO2
Permissions boundary on admin sets Bound even AdministratorAccess Attach a boundary to the set
SCPs above the OU Cap what any set can do per OU See SCP guardrails article
Short session duration Shrink leaked-credential window PT1H for sensitive sets
Portal session limit Force periodic re-auth Lower the instance sign-in session
Break-glass hygiene Recover if IdP is down One alarmed IAM user, physical MFA, sealed
CloudTrail on assignments Detect grant changes Alert on CreateAccountAssignment
Access reviews Catch stale grants Periodic assignment export + review
Least-privilege admin Limit who edits sets Scope sso-admin:* tightly
SCIM token as a secret It grants provisioning Store securely; rotate on schedule
ABAC for isolation Blast-radius by attribute Session tags + resource tags

The permission-set model composes with the rest of the IAM chain rather than replacing it: an SSO role is still subject to SCPs, RCPs, permissions boundaries, and resource policies. A permission set can grant AdministratorAccess and the user still cannot do something an SCP denies on the OU — the guardrail wins. That layering is the whole point: convenience at the identity layer, hard limits at the org layer.

Cost & sizing

IAM Identity Center itself is free — the service, the built-in identity store, permission sets, assignments, and aws sso login cost nothing. What can appear on the bill are the identity source (if you run AWS Managed Microsoft AD) and adjacent services, plus your external IdP’s own licensing.

Cost driver Charge (approx.) INR/month (approx.) Notes
Identity Center service Free ₹0 Sets, assignments, portal, CLI
Identity Center directory Free ₹0 Built-in identity store
AWS Managed Microsoft AD (Standard) ~$0.40/hr ~₹24,000 Only if AD is your source
AWS Managed Microsoft AD (Enterprise) Higher Higher Larger/multi-Region AD
AD Connector (small) ~$0.05/hr ~₹3,000 Proxy to on-prem AD
External IdP (Okta/Entra) Per your license Varies Not an AWS charge
CloudTrail (assignments/logins) Mgmt events free ~₹0 Data events extra
STS calls Free ₹0 Credential vending

Sizing is about permission-set count and assignment fan-out, not compute. Favour a small catalogue of broad, ABAC-specialized sets over hundreds of narrow ones — you have ~500 sets per instance and only ~50 provisioned per account, and each provisioned set is an IAM role counting toward the ~1,000-roles-per-account quota. If AD is your source, right-size it: AD Connector is far cheaper than Managed AD when you already have on-prem domain controllers; Managed AD earns its cost only when you need actual AWS-hosted DCs. For most orgs the correct and cheapest answer is the free built-in directory fed by an external IdP over SCIM — you pay only for the IdP you already own.

Interview & exam questions

Q1. Why is IAM Identity Center preferred over IAM users for human access in a multi-account org? It centralizes identity (one login, one place to grant/revoke), issues temporary credentials instead of static keys, enforces MFA centrally, and makes onboarding/off-boarding a group-membership change rather than per-account IAM edits. Maps to SAA-C03 and SCS-C02.

Q2. What are the three parts of an account assignment? A principal (group or user), a permission set, and a target account. All three must exist and be provisioned before a user sees a role in the portal.

Q3. A permission set materializes as what, and named how? As an IAM role in each assigned account, named AWSReservedSSO_<setname>_<hash> under path /aws-reserved/sso.amazonaws.com/. You must not hand-edit it — re-provisioning reverts changes.

Q4. You edited a permission set but access didn’t change. Why? Assigned accounts do not auto-update on a set edit; you must re-provision (provision-permission-set, or let Terraform do it). The provisioned roles were out of date.

Q5. What is the difference between SAML and SCIM in an external-IdP setup? SAML 2.0 handles authentication (sign-in); SCIM 2.0 handles provisioning (pushing and syncing users/groups). Without SCIM, a user can log in but has no groups and thus no assignments — an empty portal.

Q6. What are the two session durations and how do they differ? The permission-set session (PT1H–PT12H) is the lifetime of the role credentials; the access-portal (sign-in) session (default 8 h, up to 90 days) is how long before the user re-authenticates to the portal. They are independent.

Q7. How does ABAC work in Identity Center? Enable “attributes for access control”; user attributes from the identity source become session tags on the assumed role; permission-set policies use aws:PrincipalTag/<key> conditions so one set scopes access per department/project. Maps to SCS-C02.

Q8. Can an SCP block a permission set that grants AdministratorAccess? Yes. The SSO role is still evaluated against SCPs on the OU; an explicit Deny in an SCP overrides the admin grant. The permission set grants; the SCP caps. See AWS Organizations SCPs: Multi-Account Guardrails.

Q9. What identity sources can Identity Center use, and how many at once? The built-in Identity Center directory, Active Directory (AWS Managed Microsoft AD or AD Connector), or an external IdP via SAML+SCIM — exactly one at a time per instance, and switching is disruptive.

Q10. How does a user get CLI access? aws configure sso writes an [sso-session] block and profile to ~/.aws/config; aws sso login runs a device-authorization flow and caches an SSO token; the CLI then vends temporary role credentials per profile. Maps to DVA-C02/SOA-C02.

Q11. What breaks if sso_region is wrong? The CLI cannot find or validate the token for your instance — login/token-load errors. It must equal the instance’s home Region.

Q12. Why assign groups rather than users? So onboarding/off-boarding is a single group-membership change with zero AWS edits; per-user assignments recreate multi-account sprawl.

Quick check

  1. What is the exact triple that makes up an account assignment?
  2. A user signs in via your external IdP but the portal shows no accounts. What is the most likely cause?
  3. You removed an action from a permission set and applied it, but access still works. What did you forget?
  4. What is the maximum permission-set session duration, and what setting governs the portal sign-in session separately?
  5. Where do ABAC attributes end up on the role, and which policy condition key reads them?

Answers

  1. Principal (group/user) × permission set × target account — all three, provisioned.
  2. SCIM never pushed the user’s group into Identity Center (Okta “push groups”; Entra app-scoped groups), so the assignment targets an empty group. SAML auth works but there is nothing assigned.
  3. To re-provision the permission set to its assigned accounts (provision-permission-set / re-apply Terraform). Set edits don’t auto-propagate.
  4. PT12H for the permission-set session; the access-portal session is a separate instance setting (default 8 h, up to ~90 days).
  5. As session tags on the assumed-role session; policies read them via aws:PrincipalTag/<key> (matched against aws:ResourceTag/<key> for resource scoping).

Glossary

Term Definition
IAM Identity Center AWS service (formerly AWS SSO) for centralized human access to many accounts with temporary credentials.
Instance Your Identity Center deployment; one org instance in a single home Region.
Identity source Where users/groups come from: Identity Center directory, Active Directory, or external IdP. One at a time.
Identity store The built-in user/group directory, identified d-xxxxxxxxxx.
Permission set A reusable bundle of policies + session duration + relay state; a role template.
Account assignment The grant: principal × permission set × account.
Provisioning Creating/updating the AWSReservedSSO_* IAM role in a target account from a permission set.
AWSReservedSSO role The IAM role a permission set becomes in each account; do not hand-edit.
Access portal The web UI (awsapps.com/start) listing a user’s account+role tiles.
aws sso login CLI command running an OAuth device flow to cache an SSO token for the profile.
sso-session block The [sso-session] stanza in ~/.aws/config shared across profiles (token-based auth).
SAML 2.0 Protocol for federated authentication from an external IdP.
SCIM 2.0 Protocol for provisioning users/groups from an external IdP into the identity store.
ABAC Attribute-based access control: user attributes become session tags used in policy conditions.
Session tag A key/value on the assumed-role session, read via aws:PrincipalTag/<key>.
Permissions boundary The maximum permissions the set’s role can have — a ceiling, not a grant.
Relay state The post-login console redirect URL configured on a permission set.
Delegated administration Managing Identity Center from a member (security) account instead of the management account.

Next steps

AWSIAM Identity CenterSSOPermission SetsSCIMSAMLABACAccess Portal
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading