Skip to main content

Overview

AWS Cognito provides managed authentication with JWT tokens. The User Service integrates Cognito for:
  • User registration and login
  • Password management (reset, change)
  • Email verification
  • JWT token issuance and validation
  • Optional MFA

Architecture

Cognito User Pool Configuration

Basic Settings

Password Policy

MFA Configuration

MFA is optional to reduce friction during onboarding. High-value operations (like changing primary email) could require step-up authentication.

App Client Configuration

OAuth 2.0 Settings

Token Expiration

Access tokens cannot be revoked before expiry. Keep them short-lived. For immediate revocation needs, implement a token status check in Lambda.

API Gateway Authorizer

Cognito Authorizer Setup

The Cognito Authorizer validates JWT tokens automatically:

Extracting User Claims

In Lambda, user claims are available in the request context:

User ID Strategy

Use Cognito’s sub claim directly as the userId in DynamoDB. Pros:
  • No mapping table needed
  • Guaranteed unique
  • Available in every token
Cons:
  • UUID format, not human-readable
  • Can’t change if migrating away from Cognito

Option 2: Custom User ID

Generate custom userId (e.g., nanoid) and store mapping. Pros:
  • Portable across auth providers
  • Can use shorter IDs
Cons:
  • Requires mapping table
  • Extra lookup on every request
For most applications, using Cognito sub directly is simpler and sufficient. Only use custom IDs if you have a concrete migration plan.

Cognito Triggers

Post-Confirmation Trigger

When a user confirms their account, create the DynamoDB record:

Trigger Failure Recovery

Cognito triggers are synchronous. If the trigger fails, the user registration succeeds in Cognito but fails in DynamoDB, creating an orphaned Cognito user.
Multi-layer failure handling:
DLQ Processor:
Orphan Detection Job (Scheduled): For edge cases where both trigger and DLQ fail, run a periodic reconciliation:
The reconciliation job is a safety net. In practice, the trigger + DLQ should handle 99.9%+ of cases. Monitor the reconciliation job’s match rate - frequent orphans indicate a systemic issue.

Pre-Token Generation Trigger (Optional)

Inject custom claims into the token:
Pre-Token Generation adds latency to every token issuance. Only use if you need claims that change frequently and must be in the token.

Token Revocation Strategy

The Problem

JWT tokens are stateless. Once issued, they’re valid until expiry. If a user is suspended or deleted, their existing tokens remain valid.

Solution: Defense in Depth

1

Short Access Token TTL

1-hour access tokens limit exposure window
2

Status Check for Sensitive Operations

For high-risk operations, verify user status in DynamoDB before proceeding
3

Cognito Global Sign-Out

Invalidates all refresh tokens, forcing re-authentication

Sensitive Operations Check

Security Considerations

Never Trust Client-Provided User ID

Email Enumeration Prevention

When checking if an email exists, return generic error:

Rate Limiting

Apply rate limits on sensitive Cognito operations: