AWS Security & Identity
Cognito
User authentication, authorization, and management for web and mobile applications
Amazon Cognito provides user authentication, authorization, and user management for web and mobile applications. It handles sign-up, sign-in, social identity federation (Google, Facebook, Apple), and issues JWT tokens that your backend can validate. It is the go-to service when you need to add auth to an application without building your own identity infrastructure.
User Pools vs Identity Pools: What Each One Does
Cognito has two distinct components that are often confused. They solve different problems and are frequently used together.
| User Pool | Identity Pool (Federated Identities) | |
|---|---|---|
| Purpose | Authentication - who are you? | Authorization - what AWS resources can you access? |
| Outputs | ID token, access token, refresh token (JWT) | Temporary AWS credentials (STS) |
| Identity sources | Cognito users, social IdPs, SAML, OIDC | User Pool tokens, social IdPs, custom developer auth, unauthenticated |
| Use case | Add login/signup to an app | Let authenticated users call AWS services directly (S3, DynamoDB) |
| Backend validation | Validate JWT on your API server | AWS automatically validates identity before issuing credentials |
A typical mobile app architecture uses both: User Pool handles login and issues a JWT, then the app exchanges that JWT with an Identity Pool to get temporary AWS credentials for direct S3 uploads or DynamoDB reads.
User Pool Features and Configuration
User Pools are full-featured identity providers with customizable sign-up flows, MFA, password policies, and hosted UI.
| Feature | Description | Key config options |
|---|---|---|
| Sign-up attributes | Fields collected at registration | Email, phone, custom attributes; required vs optional |
| Password policy | Complexity and expiry rules | Min length, uppercase, numbers, symbols |
| MFA | Multi-factor authentication | SMS, TOTP (Google Authenticator); optional, required, or adaptive |
| Triggers (Lambda) | Custom logic at auth lifecycle events | Pre sign-up, post confirmation, custom auth, pre token generation |
| Hosted UI | Pre-built login pages from Cognito | Customizable CSS, custom domain (auth.example.com) |
| App clients | Per-application config for token expiry and OAuth flows | Client secret, refresh token expiry, OAuth 2.0 scopes |
| Advanced Security | Adaptive auth, compromised credential detection | Audit-only or enforce mode; risk-based challenges |
Lambda triggers are extremely powerful for customizing Cognito. The pre-token-generation trigger lets you add custom claims to JWTs (e.g., user roles from your database), which is the most common use case for integrating Cognito with a custom authorization model.
Token Types and Validation
Cognito User Pools issue three JWT tokens after successful authentication. Understanding each is critical for building secure backends.
| Token | Contains | Typical expiry | Use |
|---|---|---|---|
| ID Token | User identity claims (email, name, custom attributes) | 1 hour | Passed to backend to identify the user |
| Access Token | OAuth scopes and groups for authorization | 1 hour | Authorizing access to APIs and resources |
| Refresh Token | Opaque token for getting new ID/access tokens | 30 days (configurable) | Renew session without re-login |
# Validate a Cognito JWT in Python (using python-jose)
from jose import jwt
import requests
REGION = 'us-east-1'
USER_POOL_ID = 'us-east-1_xxxxxxxxx'
CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
# Fetch public keys from Cognito
keys_url = f'https://cognito-idp.{REGION}.amazonaws.com/{USER_POOL_ID}/.well-known/jwks.json'
keys = requests.get(keys_url).json()['keys']
def verify_token(token: str) -> dict:
header = jwt.get_unverified_header(token)
key = next(k for k in keys if k['kid'] == header['kid'])
claims = jwt.decode(
token,
key,
algorithms=['RS256'],
audience=CLIENT_ID,
)
return claimsNever trust a JWT without verifying its signature against Cognito's public JWKS endpoint. An attacker can craft a JWT with any claims if your backend skips signature verification.
Social and Enterprise Identity Federation
Cognito supports federated sign-in from social providers and enterprise IdPs, mapping external identities to Cognito users.
| Federation type | Protocol | Setup requirement |
|---|---|---|
| OIDC | Create OAuth 2.0 client in Google Cloud Console, add client ID/secret to Cognito | |
| OAuth 2.0 | Create app in Facebook Developer portal | |
| Apple | OIDC | Register with Apple Developer, handle private key rotation |
| SAML 2.0 (Okta, AD FS) | SAML | Upload IdP metadata XML to Cognito, configure attribute mapping |
| Custom OIDC | OIDC | Any OIDC-compliant IdP (Auth0, Ping, Keycloak) |
When federating from an external IdP, Cognito creates a "linked" user in the User Pool on first sign-in. The sub (subject) claim becomes the stable unique identifier. You can use the pre-signup trigger to block federation from specific email domains or to link federated identities to existing User Pool accounts.
Pricing Model and Scale Considerations
| Tier | Monthly Active Users | Price per MAU |
|---|---|---|
| First 10,000 | 0 - 10,000 | Free |
| Next 40,000 | 10,001 - 50,000 | $0.0055 |
| Next 900,000 | 50,001 - 1,000,000 | $0.0046 |
| Over 1 million | 1,000,001+ | $0.0032 |
Advanced Security Features (adaptive auth, compromised credentials) add $0.050 per MAU on top of base pricing. SAML and OIDC federation incur an additional $0.015 per MAU.
Cognito has a default rate limit of 120 sign-in requests per second per User Pool. For high-traffic applications (e.g., a viral product launch), request a limit increase in advance. Throttling at login produces 429 errors that are very visible to users.
Interview Focus Points
- 1What is the difference between a Cognito User Pool and an Identity Pool? Can you explain a use case that requires both?
- 2How do you add custom claims (like user roles) to a Cognito JWT token?
- 3How does Cognito JWT validation work on the backend? What does your server need to verify?
- 4What happens when a user signs in via Google federation - how does Cognito represent that user internally?
- 5How would you implement fine-grained access control to specific S3 prefixes based on the authenticated user's identity?
- 6What are the rate limits of Cognito and how would you handle a traffic spike at sign-in?
- 7How does Cognito Advanced Security's adaptive authentication work?
- 8What is the difference between the ID token and access token in Cognito and which should your API validate?