AWS Auth (Amazon Cognito)
Application-level user authentication and authorization with Amazon Cognito and the Amplify
client auth libraries. Verify specific limits, quotas, and exact API shapes against official AWS
documentation when precision matters; trust the docs over memory when they conflict.
Recommended: The AWS MCP server provides streamlined access to the AWS APIs used in this skill (Cognito user pool/app client/identity pool setup, API Gateway authorizers). If it is unavailable, the AWS CLI commands shown throughout work directly — the skill has no hard dependency on MCP.
When NOT to use: Amplify Gen2 backend code (
,
,
); IAM
policy/role/trust-policy authoring, STS, or IAM Identity Center console SSO; API Gateway
route/integration setup or Lambda function implementation (this skill covers only the Cognito/JWT
authorizer configuration and the purpose of Cognito Lambda triggers).
User Pool vs Identity Pool — pick first
These are different services that are frequently confused. Most apps need a user pool; add an
identity pool only if the client must call AWS services directly.
| You need... | Use | Why |
|---|
| Sign-up / sign-in, user directory, issue JWTs | User pool | It authenticates users and is an OIDC IdP |
| The signed-in client to call S3/DynamoDB/etc. directly with AWS credentials | Identity pool | It exchanges a token for temporary AWS credentials via STS |
| Both (sign in, then hit AWS resources from the browser/app) | User pool → identity pool | Identity pool trusts the user pool as its IdP |
If your app only calls your own backend/API, you do not need an identity pool — send the user
pool token to your API. See identity-pools.md.
Critical Warnings
and are FULL REPLACE, not partial updates: Any field you omit is reset to its default — calling
with only the fields you want to change silently wipes
, token validity,
, refresh-token rotation, and read/write attributes;
likewise replaces the whole roles +
structure.
Always read-modify-write:
describe-user-pool-client
(or
) first, then re-send every existing field plus your change. In an agent context the wipe is invisible — the call succeeds and only breaks later when a user hits the missing flow. See
managed-login-oauth.md and
identity-pools.md.
Don't use the implicit grant for new apps: The implicit grant (
) is legacy and returns tokens in the URL fragment. Use the
authorization code grant with PKCE (
+
) for SPAs and mobile — public clients, no client secret. See
managed-login-oauth.md.
Don't store refresh tokens in localStorage for high-value apps:
is readable by any injected script (XSS). The Amplify client library defaults to
; switch to
, keep refresh-token lifetime short, and enable
refresh token rotation +
token revocation on the app client. See
tokens-and-sessions.md.
Access-token claim customization needs a paid feature plan: The pre token generation trigger customizes the
ID token on the entry-level plan (V1), but customizing the
access token (V2/V3) requires a
paid feature plan — check the
Cognito feature plans documentation for which plan currently includes this, as plan names and inclusions can change. Don't assume access-token claims work on the entry-level plan. See
lambda-triggers.md.
App client secret + SPA = broken auth: A public client (browser/mobile) must have
no client secret. If a secret is set, token calls fail unless a
is sent, which a browser cannot protect. Generate a secret only for confidential (server-side) clients.
Don't bulk UNCONFIRMED users: When users are stuck
, prefer
so each user re-verifies via
and proves email ownership (the code likely expired or went to spam).
flips the status instantly but confirms the account
without verifying the email — the attribute stays unverified, which is dangerous when email drives password reset or account linking. Reserve it for trusted/migrated accounts. See
troubleshooting.md.
Quick Navigation
| You want to... | Go to |
|---|
| Create a user pool, sign-up/sign-in, MFA, password policy, app clients | user-pools.md |
| Add hosted UI / managed login, OAuth flows, social or SAML login, callback URLs, custom domain (ACM in us-east-1) | managed-login-oauth.md |
| Handle ID/access/refresh tokens, rotation, revocation, session termination (global sign-out vs revoke vs disable) | tokens-and-sessions.md |
| Give the client temporary AWS credentials, guest access, role mapping | identity-pools.md |
| Protect an API Gateway API with Cognito tokens (and enforce custom claims in the backend) | api-authorization.md |
| Add Cognito login in front of an Application Load Balancer (ALB ) | api-authorization.md |
| Machine-to-machine (client credentials) auth, resource servers, custom scopes | managed-login-oauth.md |
| Create user pool groups and add users to them (, ) | user-pools.md |
| Customize claims, custom auth challenge flows, migrate users, validate sign-up | lambda-triggers.md |
| Add passkey / WebAuthn sign-in ( flow, , WebAuthn enrollment) | passkeys.md |
| Configure threat protection — compromised-credentials block, adaptive auth (risk-based MFA), log delivery to CloudWatch | threat-protection.md |
| Something is broken (redirect, token, MFA, CORS, social login) | troubleshooting.md |
Common Workflows
"Add sign-up and login to my React app" → Create a user pool + a public app client (no secret), enable the hosted UI / managed login with the authorization code grant with PKCE, wire the Amplify client library. See user-pools.md and managed-login-oauth.md.
"Add Google / social login" → Register the social IdP on the user pool, map attributes, add the provider to the app client and hosted UI. See managed-login-oauth.md.
"Only authenticated users should call my API" → HTTP API → JWT authorizer; REST API → Cognito user pools authorizer. See api-authorization.md.
"Let the browser upload to S3 after login" → User pool for sign-in, then an identity pool to vend scoped temporary credentials. See identity-pools.md.
Troubleshooting
| Error/Symptom | Likely Cause | Quick Fix |
|---|
| / redirect to wrong URL after login | Callback URL not registered, or scheme/trailing-slash/case differs | Add the exact callback URL (incl. scheme and path) to the app client's Allowed callback URLs |
| Token calls fail with "unable to verify secret hash" | Client secret set on a public (SPA/mobile) client | Recreate the app client with no secret, or send from a confidential client |
| Users get 401 from API Gateway with a valid token | Wrong token type or audience/issuer mismatch | HTTP JWT authorizer: issuer https://cognito-idp.{region}.amazonaws.com/{userPoolId}
, audience = app client id; send the token the authorizer expects |
| CORS errors calling the hosted UI / token endpoint | Browser calling cross-origin, or missing CORS on your API | Do the code exchange with PKCE; don't proxy the token endpoint from the browser |
| Social login user "already exists" / attribute conflict | Same email across providers creates separate users | Enable attribute mapping + account linking; treat email as non-unique across IdPs |
Full tables in troubleshooting.md.
Security Considerations
- Public clients (SPA/mobile): no client secret, authorization code grant with PKCE, request least-privilege scopes.
- Enable MFA (TOTP or SMS), a strong password policy, and advanced security / threat protection where available.
- Short access-token lifetime; enable refresh token rotation and token revocation; prefer over .
- Identity pools: scope the authenticated IAM role tightly; disable unauthenticated (guest) access unless required.
- Validate JWTs against the user pool JWKS (, /, , ) on every protected request. Use a maintained library such as rather than hand-rolling verification.
- Set security headers on the app's web pages: (restrict script sources to mitigate token-stealing XSS),
Strict-Transport-Security
(HSTS), / (clickjacking on login pages), and X-Content-Type-Options: nosniff
.
- Enable logging and monitoring: CloudTrail for Cognito API events (sign-up/sign-in/admin), user pool threat protection (adaptive auth + event logging), CloudWatch alarms on failed/throttled auth, and API Gateway access logging for authorizer decisions.
- All Cognito and API endpoints are HTTPS/TLS only; enable encryption at rest with a customer-managed KMS key (and restricted key access) on CloudWatch Log groups, SNS topics used for MFA/notifications, and any identity-pool-fronted upload buckets.
- If using SNS for MFA/notification delivery, enable server-side encryption (KMS) on the topic, and keep SMS/email message content limited to what the recipient needs — don't include more PII than the message requires.
- References: Amazon Cognito security features (user pools), Amazon Cognito security (top-level, incl. identity pools), and IAM/STS best practices.
Where to Look When This Skill Is Silent
When you need depth beyond this skill — exact parameter shapes, current limits, edge behaviors — fall back to the authoritative AWS sources rather than guessing. Pointers age much slower than content, so this map stays useful without the skill having to grow.
- API reference (exact params, defaults, errors): Cognito User Pools API and Cognito Identity API
- Developer Guide (concepts, workflows): Amazon Cognito Developer Guide
- Quotas, rate limits, session-cookie lifetime: Cognito quotas
- Feature plans / tier gating: Cognito feature plans
- Pricing: Amazon Cognito pricing
- CLI reference: aws cognito-idp and aws cognito-identity
Not Covered By This Skill
- Amplify Gen2 backend (, , ).
- IAM policy/role/trust-policy authoring, STS, IAM Identity Center console SSO.
- API Gateway route/integration setup and Lambda function implementation (this skill covers only the Cognito/JWT authorizer configuration and the purpose of Cognito Lambda triggers).