☰ All modules Tier 1 · Advanced Identity (Cognito, STS, cross-account roles) GuideCheat sheet ‹ security-encryptioncicd ›
Contents
  1. Cognito user pools vs identity pools
  2. User pool sign-up, sign-in and MFA
  3. User pool tokens and JWT validation
  4. User pool Lambda triggers
  5. Managed login, domains and OAuth
  6. Feature plans and threat protection
  7. ALB authentication
  8. Identity pools
  9. STS and cross-account roles
  10. STS with MFA
  11. Policy evaluation
  12. Policy variables
  13. Managed vs inline policies and PassRole
  14. AWS Directory Service
  15. Numbers to know
  16. Decision rules
  17. Memory hooks

Advanced Identity (Cognito, STS, cross-account roles) — Cheat Sheet (DVA-C02)

Verified against AWS documentation on 2026-10-12 · ⚠️ = changed vs the course or older material: learn the value shown here (full list in notes/advanced-identity-guide.md#changed-vs-older-material; rows you confirm also go to notes/current-facts.md) · explanations and examples: notes/advanced-identity-guide.md.

Cognito user pools vs identity pools

Topic Current facts Memory hook
Cognito user pool User directory + OIDC provider: signs users in (local, or federated Google, Facebook, Apple, Amazon, SAML, OIDC) and issues ID, access and refresh tokens Pool of users → tokens
Cognito identity pool Swaps a user pool ID token, social/OIDC/SAML token or nothing (guest) for temporary AWS credentials of an IAM role via STS Pool of identities → AWS keys
User pool + identity pool together Sign in at the user pool, pass the ID token in Logins (cognito-idp.<region>.amazonaws.com/<pool-id>), call AWS services directly Authenticate, then authorize
Guest (anonymous) access Only identity pools have unauthenticated identities (AllowUnauthenticatedIdentities) Guests live in identity pools
Identity pool credential fields AccessKeyId, SecretKey, SessionToken, Expiration; enhanced-flow credentials last 1 h
Cognito vs IAM users App customers → Cognito; people and tools that run the AWS account → IAM / IAM Identity Center
Cognito Sync ⚠️ No longer open to new customers → AWS AppSync or DynamoDB Sync has sunk

User pool sign-up, sign-in and MFA

Topic Current facts Memory hook
User pool app client Per-app settings: auth flows, OAuth grants, token lifetimes, attribute read/write, optional client secret
Client secret rules Public (browser/mobile) clients have none; can't be added or removed after creation (new client); up to 2 secrets for rotation Secrets live on servers
SECRET_HASH Base64(HMAC-SHA256(key = client secret, msg = username + client ID)); missing → "Unable to verify secret hash for client"
User account states SignUp → UNCONFIRMED → CONFIRMED (code, AdminConfirmSignUp or pre sign-up trigger); admin-created → FORCE_CHANGE_PASSWORD; imported → RESET_REQUIRED
User pool auth flows USER_SRP_AUTH (password never sent, best practice), USER_PASSWORD_AUTH, ADMIN_USER_PASSWORD_AUTH (IAM creds), CUSTOM_AUTH, REFRESH_TOKEN_AUTH, USER_AUTH (choice-based, Essentials+) SRP = Secret Remains Private
Default ExplicitAuthFlows ALLOW_REFRESH_TOKEN_AUTH, ALLOW_USER_SRP_AUTH, ALLOW_CUSTOM_AUTH
User pools API authorization Public (client ID): SignUp, InitiateAuth, ForgotPassword; token: GetUser, UpdateUserAttributes, GlobalSignOut; IAM: all Admin* and configuration calls
User pool MFA factors SMS (SNS role), TOTP (AssociateSoftwareToken + VerifySoftwareToken), email OTP (Essentials/Plus + SES); passkeys and passwordless OTP are first factors (Essentials/Plus)
User pool MFA rules Off / Optional / Required; federated users get MFA from their IdP; adaptive auth needs Optional; Required impossible with OTP passwordless
Fixed at user pool creation Sign-in identifiers (username vs email/phone vs aliases) and required attributes
Custom attributes Up to 50, custom: prefix, can't be removed or renamed, mutable or immutable
sub attribute Immutable unique user ID → use it as your database key The sub never changes
PreventUserExistenceErrors ENABLED = generic errors; LEGACY (API default) = UserNotFoundException
User pool exceptions UserNotConfirmedException, PasswordResetRequiredException, NotAuthorizedException, UsernameExistsException, CodeMismatchException, UserLambdaValidationException, TooManyRequestsException, FeatureUnavailableInTierException
UpdateUserPool / UpdateUserPoolClient Omitted settings reset to defaults → send the full configuration Update = replace
Blocking SDK sign-in AWS WAF web ACL on the user pool; removing COGNITO from an app client only hides it in managed login

User pool tokens and JWT validation

Topic Current facts Memory hook
ID token Identity claims (sub, attributes, cognito:groups); aud = app client ID; token_use = id ID = who
Access token scope, client_id, username, groups; authorizes APIs and self-service calls; token_use = access Access = what
Refresh token Opaque and encrypted; buys new ID and access tokens
Cognito token lifetimes ID/access default 1 h (5 min–1 day); refresh default 30 days (1 h–3,650 days)
JWT validation steps Signature (JWKS key by kid, RS256) → exp → iss → aud / client_id → token_use Sign, expiry, issuer, audience, use
Cognito JWKS URL https://cognito-idp.<region>.amazonaws.com/<pool-id>/.well-known/jwks.json
JWT verification library aws-jwt-verify: CognitoJwtVerifier.create({ userPoolId, tokenUse, clientId })
Token refresh options REFRESH_TOKEN_AUTH, GetTokensFromRefreshToken, token endpoint grant_type=refresh_token
Refresh token rotation ⚠️ Optional per client; new refresh token each refresh; grace ≤ 60 s; needs GetTokensFromRefreshToken or token endpoint; same expiry window
Ending Cognito sessions RevokeToken (refresh token), GlobalSignOut (own access token), AdminUserGlobalSignOut (IAM); offline validators still accept unexpired access tokens
Default scope from API sign-in Access token carries only aws.cognito.signin.user.admin
API Gateway Cognito authorizer token Accepts ID or access token; methods with authorization scopes need the access token
Token for identity pools The user pool ID token

User pool Lambda triggers

Topic Current facts Memory hook
Pre sign-up trigger Allow-list or refuse new accounts; skip the code with autoConfirmUser, autoVerifyEmail, autoVerifyPhone; also fires for AdminCreateUser and a first federated sign-in Pre-approve
Post confirmation trigger Runs once the account is confirmed (also after ConfirmForgotPassword): create the profile row, send a welcome
Pre / post authentication triggers Pre: refuse a sign-in by throwing an error; post: audit a successful one; neither changes tokens
Pre token generation trigger Claims, groups, roles; V1_0 ID token; ⚠️ V2_0 adds access-token claims and scopes; V3_0 adds M2M; V2/V3 need Essentials or Plus Last stop before tokens
Migrate user trigger User missing at password sign-in or ForgotPassword; finalUserStatus CONFIRMED keeps the password; never fires for SRP or passwordless Migration needs the password
Custom message trigger smsMessage, emailMessage, emailSubject, must include the code placeholder
Custom auth challenge triggers Define → Create → Verify auth challenge in CUSTOM_AUTH; not available in managed login
Custom email/SMS sender triggers Third-party delivery; codes encrypted with your KMS key; configured by API/CLI only (KMSKeyID)
Trigger timeout Synchronous, 5 s, not adjustable (custom senders excepted) Five seconds or fail
Trigger invoke permission Lambda resource policy for cognito-idp.amazonaws.com (aws:SourceArn = pool ARN); console adds it, CLI/IaC must add it
Trigger rejection error API returns UserLambdaValidationException "<trigger> failed with error …"
Federated sign-in and triggers No custom auth, migrate user, custom message or custom sender triggers

Managed login, domains and OAuth

Topic Current facts Memory hook
Managed login ⚠️ Since 22 Nov 2024: branding editor, passkeys, localisation; Essentials/Plus; classic hosted UI in all plans and the only one in Lite; one branding version per domain
ManagedLoginVersion 1 = classic hosted UI, 2 = managed login
App clients created by API Need CreateManagedLoginBranding before managed login pages work
Prefix domain format <prefix>.auth.<region>.amazoncognito.com
Custom domain requirements ACM certificate in us-east-1, parent-domain A record, alias to Cognito's CloudFront domain; ≤ 4 per Region The certificate lives in Virginia
User pool OAuth endpoints /oauth2/authorize, /oauth2/token, /oauth2/userInfo, /oauth2/revoke, /login, /logout, /oauth2/idpresponse, /saml2/idpresponse
Authorization code + PKCE Most secure grant; tokens come from the token endpoint; refresh token included Code + PKCE for public apps
Implicit grant Tokens in the URL fragment, no refresh token, no PKCE → legacy and testing only
Client credentials grant M2M; client secret required; custom scopes only; access token only; billed separately; GetClientToken works without a domain Machines get access only
OAuth scopes in Cognito openid → ID token; aws.cognito.signin.user.admin → self-service APIs; custom <resource-server>/<scope>
Managed login session cookie Lasts 1 h; /logout clears it
Callback URL rules HTTPS (http only for localhost), absolute, pre-registered, no fragment, ≤ 100 per app client
Federated user sign-in Only through /oauth2/authorize or managed login, never InitiateAuth

Feature plans and threat protection

Topic Current facts Memory hook
Lite plan ⚠️ Basic sign-in, federation, classic hosted UI, SMS/TOTP MFA, ID-token customisation, triggers, M2M
Essentials plan ⚠️ Default for new pools: + managed login, passkeys, passwordless OTP, email MFA, choice-based sign-in, access-token customisation
Plus plan ⚠️ Essentials + threat protection (adaptive auth, compromised credentials, activity log export) Plus protects
Threat protection modes AdvancedSecurityMode AUDIT / ENFORCED requires tier PLUS; run audit-only first (≥ 2 weeks)
Compromised-credentials check Sign-in, sign-up, password change; block or allow; password flows only (not SRP, not custom auth)
Adaptive authentication Risk low/medium/high → allow, optional MFA, require MFA, block (+ notify); user pool MFA must be Optional
Threat protection gaps Doesn't cover federated sign-in or M2M; no rate limiting → add AWS WAF
Threat protection logs Export to CloudWatch Logs, S3 or Data Firehose
Feature not in plan FeatureUnavailableInTierException

ALB authentication

Topic Current facts Memory hook
ALB authenticate actions authenticate-cognito, authenticate-oidc; HTTPS listeners only
App client for ALB auth Client secret + code grant + openid; callback https://<ALB DNS or CNAME>/oauth2/idpresponse in lowercase
OnUnauthenticatedRequest authenticate (default, redirect), allow (no claims), deny (HTTP 401 when there is no session)
ALB authenticate defaults SessionTimeout 604,800 s (7 days); cookie AWSELBAuthSessionCookie; scope openid
x-amzn-oidc-data header User claims JWT signed with ES256; check signer = ALB ARN; key from public-keys.auth.elb.<region>.amazonaws.com/<kid> Data is signed
Legacy ALB headers ⚠️ x-amzn-oidc-accesstoken and x-amzn-oidc-identity are unsigned → never authorize on them
ALB auth limits Sign-in must finish in 15 min (else 401); claims + token > 11 KB → HTTP 500
ALB jwt-validation action ⚠️ Since 12 Nov 2025 for M2M bearer JWTs: RS256, iss + exp + ≤ 10 claims, JWKS ≤ 150 KB and ≤ 10 keys
SAML sign-in at an ALB Federate the SAML IdP into a user pool, then authenticate-cognito

Identity pools

Topic Current facts Memory hook
Identity pool enhanced flow GetId → GetCredentialsForIdentity; Cognito picks the role; credentials 1 h; role in the same account
Identity pool basic flow GetId → GetOpenIdToken → AssumeRoleWithWebIdentity; client picks the role; keep off unless needed; no role mappings
Developer-authenticated identities Backend calls GetOpenIdTokenForDeveloperIdentity with IAM credentials
Identity pool role trust policy Federated: cognito-identity.amazonaws.com, sts:AssumeRoleWithWebIdentity, cognito-identity.amazonaws.com:aud (required) + :amr authenticated/unauthenticated aud = which pool, amr = who
STS API behind identity pools ⚠️ AssumeRoleWithWebIdentity (the course writes "AssumeRoleForWebIdentity")
Guest scope-down policy Enhanced-flow guests limited to a service list (S3, DynamoDB, Lambda, SQS, SNS, Kinesis, API Gateway, CloudWatch…); others → NotAuthorizedException
Role from token User pool group role → cognito:preferred_role (lowest precedence number) / cognito:roles; optional CustomRoleArn
Role-mapping rules Claim match → role; first match wins; ≤ 25 per provider; AmbiguousRoleResolution AuthenticatedRole or Deny
Attributes for access control Token claims → session tags → ${aws:PrincipalTag/<key>}; trust policy also needs sts:TagSession
Identity pool per-user variable ${cognito-identity.amazonaws.com:sub} = identity ID <region>:<guid>
Identity pool public APIs GetId, GetCredentialsForIdentity need no AWS credentials

STS and cross-account roles

Topic Current facts Memory hook
AssumeRole duration 900 s up to the role's maximum; default 3,600 s
Role maximum session duration ⚠️ 1–12 h (aws iam update-role --max-session-duration); asking for more fails
Role chaining limit Role-to-role sessions last at most 1 h, whatever the role's maximum; a chained request for more fails A chain lasts one hour
GetSessionToken IAM user; 15 min–36 h, default 12 h; root ≤ 1 h; used with MFA
GetFederationToken IAM user; 15 min–36 h, default 12 h; no session policy → no permissions
AssumeRoleWithWebIdentity guidance ⚠️ Mobile apps → use Cognito; workloads with an OIDC IdP (e.g. CI/CD) → calling it directly is fine
AssumeRoot ⚠️ Org management account or delegated admin; root task on a member account; ≤ 900 s; Regional endpoint only
GetCallerIdentity Needs no permission; works even under an explicit deny
Cross-account assume requirement Target role's trust policy + sts:AssumeRole allow in the caller's identity policy Both doors open
Same-account assume requirement Identity-policy allow (trust trusts the account) OR trust policy naming the user
External ID sts:ExternalId trust condition for third parties; 2–1,224 chars; stops the confused deputy
Switching to a role You give up your own permissions; resource-based policies let you keep them
Session policies 1 inline + ≤ 10 managed ARNs, ≤ 2,048 chars combined; result = intersection
Session tags ≤ 50; key 128 / value 256 chars; TransitiveTagKeys survive chaining; need sts:TagSession
Limits of role credentials Can't call GetSessionToken or GetFederationToken
STS global endpoint ⚠️ Served in the caller's Region for default-enabled Regions; opt-in Regions → us-east-1; prefer Regional endpoints
STS request quota 600 RPS per account per Region, shared by AssumeRole, GetCallerIdentity, GetSessionToken…

STS with MFA

Topic Current facts Memory hook
MFA condition keys aws:MultiFactorAuthPresent (only in temporary-credential requests), aws:MultiFactorAuthAge (seconds since MFA)
Recommended MFA deny Deny + BoolIfExists aws:MultiFactorAuthPresent false (also blocks long-term keys) If it doesn't exist, it isn't MFA
MFA allow form Allow + Bool aws:MultiFactorAuthPresent true
MFA deny pitfall Deny + Bool false lets long-term access-key requests through
STS MFA parameters SerialNumber (device serial or arn:aws:iam::<acct>:mfa/<name>) + TokenCode (6 digits)
GetSessionToken credential limits No IAM calls without MFA; STS only AssumeRole / GetCallerIdentity; no console sign-in
Role that requires MFA Trust policy Bool aws:MultiFactorAuthPresent true; call assume-role --serial-number --token-code

Policy evaluation

Topic Current facts Memory hook
Evaluation order Explicit deny → RCPs ⚠️ → SCPs → resource-based → identity-based → permissions boundary → session policy Deny first, then every gate
Default decision Implicit deny
Explicit deny Overrides any allow anywhere
Cross-account evaluation Trusted and trusting account evaluations must both allow
Same-account resource-based policy Naming a user or role session grants directly; naming a role ARN is still limited by boundary / session policy
Policies that must explicitly allow Role trust policies and KMS key policies
SCP scope Member accounts incl. their root user; not the management account; not service-linked roles; never grant
Resource control policies ⚠️ Since 13 Nov 2024: cap resource permissions in member accounts for any caller; launched for S3, STS, KMS, SQS, Secrets Manager, now dozens of services
AccessDenied message hints "with an explicit deny in a <type> policy" / "because no <type> policy allows the <action> action"; types include SCP, RCP, identity-based, resource-based, session, boundary, VPC endpoint, role trust
Policy testing tools aws iam simulate-principal-policy, IAM Access Analyzer validation, sts decode-authorization-message

Policy variables

Topic Current facts Memory hook
Policy language version for variables "Version": "2012-10-17"; otherwise ${…} is literal text
Where variables work Resource (after the fifth colon) and string/ARN conditions; never Action
${aws:username} IAM users only; absent for roles, root and federated users Usernames are for users
${aws:userid} values Role session role-id:session-name; EC2 role role-id:instance-id; root = account ID
${aws:PrincipalTag/<key>} Tags on users, roles or sessions → ABAC
Identity pool policy variable ${cognito-identity.amazonaws.com:sub} for per-identity S3 prefixes and dynamodb:LeadingKeys
Variable with no value StringEquals doesn't match, StringNotEquals does; default syntax ${aws:PrincipalTag/team, 'company-wide'}
S3 home-folder policy s3:ListBucket on the bucket with s3:prefix; object actions on bucket/home/${aws:username}/*

Managed vs inline policies and PassRole

Topic Current facts Memory hook
AWS managed policy Created and updated by AWS; read-only; job functions such as AdministratorAccess, PowerUserAccess, ReadOnlyAccess
Customer managed policy Reusable; ≤ 5 versions; one default version; roll back with SetDefaultPolicyVersion Managed = many + versions
Inline policy Embedded in one identity; deleted with it; no versions Inline = one-to-one
Freezing a managed policy Deny iam:CreatePolicyVersion and iam:SetDefaultPolicyVersion
iam:PassRole Permission, not an API → no CloudTrail event; checked when a role is handed to a service No pass, no deploy
Scoping iam:PassRole Role ARN(s) + iam:PassedToService (+ iam:AssociatedResourceArn); not iam:ResourceTag
Passed role's trust policy Must name the receiving service principal (e.g. lambda.amazonaws.com)
PassRole across accounts Not possible; use a role in the service's own account
One role per workload EC2 instance profile, Lambda execution role, ECS task role, CodeBuild service role
ECS task roles on EC2 ⚠️ Work out of the box on current ECS-optimized AMIs; ECS_ENABLE_TASK_IAM_ROLE=true only for other AMIs or external instances
Long-term access keys ⚠️ Only where roles can't be used; humans → IAM Identity Center; workloads outside AWS → IAM Roles Anywhere or OIDC/SAML federation Borrow credentials, don't own them

AWS Directory Service

Topic Current facts Memory hook
AWS Managed Microsoft AD Real AD (Windows Server 2019) in 2 AZs; Standard ~30,000 / Enterprise ~500,000 objects; trusts; RADIUS MFA; RDS for SQL Server Real AD, run by AWS
AD Connector Proxy to on-premises AD; no directory data in AWS; RADIUS MFA; seamless EC2 domain join Connector = a cable
Simple AD Samba 4, basic AD features; no trusts, MFA, LDAPS or schema extensions Simple = standalone
Simple AD availability ⚠️ Closed to new customers since 30 Jul 2026; existing customers keep it; newcomers use Managed Microsoft AD or AD Connector
Managed Microsoft AD Hybrid Edition ⚠️ Since 30 Jul 2025: extends a self-managed AD into AWS with the same identities
Customer sign-up for apps Amazon Cognito, not Directory Service

Numbers to know

Item Value Note
ID and access token validity Default 1 h; 5 min–1 day Per app client
Refresh token validity Default 30 days; 1 h–3,650 days Per app client
Refresh token rotation grace period Up to 60 s ⚠️ Rotation is optional
Authentication session (AuthSessionValidity) 3–15 min Time to answer each challenge; default ⚠️ unverified
Managed login session cookie 1 h Cleared by /logout
Sign-up confirmation code 24 h ResendConfirmationCode for a new one
Forgot-password code 1 h
MFA code validity 3–15 min
Lambda trigger response time 5 s, not adjustable Synchronous triggers
Custom attributes per user pool 50 Not adjustable
User pools per Region 1,000 Adjustable to 10,000
App clients per user pool 1,000 Adjustable to 10,000
Users per user pool 40,000,000 Adjustable
Client secrets per app client 2 For rotation
UserAuthentication request quota 120 RPS Adjustable; sign-in + refresh
UserCreation request quota 50 RPS Adjustable
ClientAuthentication (client credentials) quota 150 RPS Not adjustable → cache M2M tokens
Built-in Cognito email sender 50 emails per day per account Use SES for production
Custom domains per Region 4 Certificate in us-east-1
Callback URLs per app client 100
Identity pool enhanced-flow credentials 1 h
Identity pools per account 1,000 Adjustable
Role-mapping rules per identity provider 25 Not adjustable
GetId / GetCredentialsForIdentity rate 25 RPS / 200 RPS Cache the identity ID
ALB authentication SessionTimeout default 604,800 s (7 days)
ALB sign-in completion limit 15 min Then HTTP 401
ALB user claims + access token size 11 KB Above → HTTP 500
ALB jwt-validation JWKS limits ≤ 150 KB, ≤ 10 keys; ≤ 10 extra claims ⚠️ New Nov 2025
AssumeRole session duration 900 s up to the role maximum; default 3,600 s ⚠️ Not "1 hour max"
Role MaxSessionDuration 1–12 h ⚠️
Role chaining session 1 h maximum Asking for more fails
GetSessionToken / GetFederationToken (IAM user) 900–129,600 s (36 h); default 43,200 s (12 h) Root: max 3,600 s
AssumeRoot session ≤ 900 s ⚠️ New Nov 2024
Session policies 1 inline + 10 managed ARNs, 2,048 chars combined
Session tags 50; key 128 chars, value 256 chars
External ID / role session name length 2–1,224 / 2–64 characters
STS request quota 600 RPS per account per Region Shared across STS calls
Managed policies per role / user / group 20 (→25) / 10 (→20) / 10 ⚠️ Role default was 10
IAM policy size limits Inline: user 2,048, group 5,120, role 10,240 chars; managed 6,144 chars Whitespace not counted
Managed policy versions / role trust policy length 5 versions / 2,048 chars (→ 8,192) ⚠️ Trust max was 4,096

Decision rules

Memory hooks