Cognito
Amazon Cognito is a fully managed AWS service that handles authentication, authorization, and user management for web, mobile, and serverless applications — without requiring you to build or maintain custom user directories, password hashing, token logic, or session management.
Users can sign in directly with credentials they create in your app (username/password), or federate through third-party identity providers (IdPs) such as:
Google
Facebook
Login with Amazon
Sign in with Apple
SAML 2.0 providers (e.g., Microsoft Entra ID / Active Directory)
OpenID Connect (OIDC) providers
Cognito supports secure sign-up, sign-in, MFA (SMS/email/TOTP), password policies, custom attributes, user groups, token issuance, and session revocation — all with built-in security and compliance features.
Core Components
Cognito has two main services that solve complementary problems:
User Pools
Authentication + user directory
ID Token, Access Token, Refresh Token (JWTs)
User sign-up/sign-in, federated login, API protection
Yes
Identity Pools
Authorization — temporary AWS credentials
Temporary IAM credentials (access key, secret key, session token)
Direct client access to S3, DynamoDB, Lambda, etc.
Yes (but usually paired)
User Pools act as your user directory and identity provider (IdP), issuing JSON Web Tokens (JWTs) after successful authentication.
Identity Pools (formerly Federated Identities) map authenticated (or guest) users to temporary AWS IAM credentials for fine-grained access to AWS resources.
Best practice (2026): Use User Pools for login + API auth. Add Identity Pools only when clients need direct AWS service access (e.g., browser uploads to S3).
User Pools and Identity Pools can be used separately or together — the most common modern pattern is User Pools → Identity Pools for authenticated flows.
Cognito Tokens – The Three Types
After successful authentication in a User Pool, Cognito issues three JWTs (or opaque tokens):
ID Token
Purpose: Proves who the user is (authentication / OpenID Connect identity).
Contains: User claims (sub/user ID, email, name, phone, custom attributes, groups).
Best used for: Frontend UI (display name/email), identity-based decisions in your app.
Not primarily for API authorization (contains sensitive PII — avoid sending unnecessarily).
Lifetime: Default 1 hour (configurable).
Access Token
Purpose: Authorizes actions/scopes the user can perform (OAuth 2.0 authorization).
Contains: Scopes (e.g.,
openid,profile, custom scopes), groups, client_id.Best used for: Calling your APIs (via API Gateway JWT authorizer), user self-service operations (e.g., UpdateUserAttributes — requires
aws.cognito.signin.user.adminscope).2026 best practice: Preferred token for backend API authorization to follow least-privilege and separation of concerns.
Refresh Token
Purpose: Obtain new ID + Access tokens without re-login.
Opaque/encrypted — readable only by Cognito.
Lifetime: Default 30 days (configurable up to 10 years).
Security: Store securely (HttpOnly cookie or secure storage), never expose client-side. Revoke on logout.
Token best practices (2026):
Use Access Token for API calls when possible (scopes + least privilege).
Use ID Token safely with Cognito's native API Gateway authorizer (AWS verifies it securely).
Never store tokens in localStorage (XSS risk) — use secure cookies or Amplify Auth helpers.
Enable token revocation to invalidate tokens on logout, compromise, or account disable.
Sample Token Payloads
ID Token (decoded JWT payload):
Contains user identity claims (PII). Use for displaying user info in the UI or passing identity to Identity Pools.
token_useis always"id".
Access Token (decoded JWT payload):
Contains scopes and groups but no PII (no email, name, or phone). Use for API authorization.
token_useis always"access". Note:client_idreplacesaud.
Refresh Token:
The Refresh Token is encrypted and opaque — it cannot be decoded or inspected. Only Cognito can read it. It contains no user-readable claims. Your application stores it securely and sends it back to Cognito to obtain new ID and Access Tokens.
Key differences at a glance:
token_use
"id"
"access"
N/A (opaque)
User PII (email, name, phone)
Yes
No
N/A
cognito:groups
Yes
Yes
N/A
scope
No
Yes
N/A
Audience field
aud (client ID)
client_id
N/A
Custom attributes
Yes (custom:*)
No
N/A
Decodable
Yes (JWT)
Yes (JWT)
No (encrypted)
Default lifetime
1 hour
1 hour
30 days
Typical Authentication Flow
Cognito User Pool Authorizer (API Gateway)
A Cognito User Pool Authorizer is a built-in API Gateway feature that validates Cognito-issued JWTs before your backend code runs. It offloads authentication entirely to the API Gateway layer, so your Lambda or backend never receives unauthenticated requests.
How It Works
The client sends a request with
Authorization: Bearer <token>(ID Token or Access Token).API Gateway passes the token to the Cognito User Pool Authorizer.
The authorizer validates the token against the configured User Pool (checks signature, expiration, issuer
iss, and audienceaud/client_id).If valid, the request proceeds to the backend with the decoded claims available in
event.requestContext.authorizer.claims(REST API) orevent.requestContext.authorizer.jwt.claims(HTTP API).If invalid or expired, API Gateway returns
401 Unauthorizedimmediately — your backend is never invoked.
When to Use
Protect APIs behind Cognito sign-in
Yes — this is the primary use case
Simple group-based access (e.g., admins vs users)
Yes — check cognito:groups claim in Lambda
OAuth2 scope-based authorization (e.g., read:orders)
Yes — use Access Token with custom scopes
Public + authenticated mixed endpoints
Yes — set authorizer per route/method
Fine-grained per-resource authorization (e.g., user can only edit own records)
Partially — authorizer handles authentication, your backend handles resource-level authorization using claims
Non-Cognito identity providers only
No — use a Lambda authorizer or JWT authorizer with your IdP
Machine-to-machine (M2M) with client credentials
Yes — use Cognito client credentials grant + Access Token with custom scopes
When NOT to Use
Custom token validation logic — If you need to check tokens against a database, call external services, or apply business rules during auth, use a Lambda Authorizer instead.
Non-JWT authentication — API keys, basic auth, or custom headers require a Lambda Authorizer.
Third-party IdP without Cognito — If you use Auth0, Okta, or another IdP directly (not federated through Cognito), use the JWT Authorizer (HTTP API) or a Lambda Authorizer (REST API).
Setup: REST API (API Gateway v1)
Create the Authorizer in API Gateway Console:
Go to your REST API → Authorizers → Create New Authorizer
Type: Cognito
Cognito User Pool: select your pool
Token Source:
Authorization(the header name)
Attach to Methods:
Go to Resources → select a method (e.g.,
GET /orders)Method Request → Authorization → select your Cognito authorizer
Deploy the API to a stage.
CloudFormation / SAM example (REST API):
Setup: HTTP API (API Gateway v2)
HTTP APIs use a JWT Authorizer that works natively with Cognito User Pools:
Accessing Claims in Lambda
Once the authorizer validates the token, your Lambda receives the decoded claims:
ID Token vs Access Token — Which to Send?
Contains
User identity claims (email, name, sub, groups)
Scopes, groups, client_id
REST API Cognito Authorizer
Supported (validates aud = client ID)
Supported (validates client_id)
HTTP API JWT Authorizer
Supported
Preferred — supports scope-based authorization
Scope enforcement
Not applicable
Authorizer can require specific scopes per route
Best practice
Use when backend needs identity claims
Use for API authorization (least privilege)
Recommendation: Send the Access Token for API calls. If your backend needs user attributes (email, name), either:
Include them as custom claims via a Pre Token Generation Lambda Trigger, or
Look up the user by
subfrom the Access Token.
Common Pattern: Group-Based Authorization
Cognito User Pool Authorizer vs Lambda Authorizer vs IAM Authorization
Auth mechanism
Cognito JWT validation
Custom code (any token/header)
AWS Sig v4 signed requests
Setup complexity
Low (configuration only)
Medium (write + deploy Lambda)
Low (IAM policies)
Latency
Low (built-in validation)
Higher (Lambda cold start possible)
Low
Caching
Built-in (configurable TTL)
Optional (configurable TTL)
N/A
Cost
No extra cost
Lambda invocation cost
No extra cost
Custom logic
No (validation only)
Yes (database lookups, business rules)
No
Best for
Cognito-based apps
Custom IdPs, complex auth rules
AWS service-to-service, SDK clients
Last updated