Custom Domains with Route 53, Cognito, and TLS
Custom Domains with Route 53, Cognito, and TLS
TL;DR
- Route 53 manages DNS; ACM issues and auto-renews public TLS certificates.
- Cognito handles authentication: user pools (managed users), identity pools (federated), hosted UI, JWT tokens.
- OAuth 2.0 callback URLs must exactly match domain configuration during custom-domain migration; mismatch breaks login.
- API Gateway authorizers validate JWT tokens; enforce per-user scopes and claims to prevent privilege escalation.
- Tenant isolation: JWT claims include user/tenant ID; enforce in application code to prevent cross-tenant data access.
- Monitor certificate expiry (ACM alerts); test failover paths (auth service down, cert revocation).
Core Concepts
Route 53 and DNS Architecture
Subdomain structure:
app.example.com: Web application frontend (CloudFront or ALB).api.example.com: REST API (API Gateway or ALB).auth.example.com: Cognito hosted UI (OAuth 2.0 login page).
Route 53 records:
app.example.com→ CloudFront distribution CNAME or ALB DNS name.api.example.com→ API Gateway custom domain or ALB DNS name.auth.example.com→ Cognito hosted UI endpoint (or custom domain via Cognito-hosted UI).
Failover:
- Primary record points to active region (us-east-1 ALB).
- Secondary record points to standby region (us-west-2 ALB) or S3 static error page.
- Route 53 health checks monitor primary; if unhealthy, traffic routes to secondary.
ACM: TLS Certificate Lifecycle
Certificate provisioning:
- ACM issues certificates at no cost (only for AWS resources: CloudFront, ALB, API Gateway).
- Certificate validation: DNS validation (ACM adds CNAME record to Route 53 automatically) or email validation.
- Auto-renewal: ACM renews 60 days before expiry; no manual intervention required.
Common issue: Custom domain migration. Old cert is for app.example.com; new domain is api.example.com. Each subdomain requires its own cert. ACM certificate renewal is automatic only if the cert is actually being used.
Monitoring: CloudWatch event when ACM certificate is near expiry (60+ days out) or rejected for renewal. SNS notification to ops team.
Cognito: Authentication and Authorization
User Pools: Managed user database. Cognito handles password storage, MFA, password reset, email verification.
Identity Pools (Federated Identities): Map external identity providers (social login, SAML, custom) to AWS credentials. Users can assume temporary AWS IAM role.
Hosted UI: Pre-built login page hosted by Cognito. Implements OAuth 2.0 authorization code flow. Redirects to app after successful login.
App Clients: OAuth applications registered in the user pool. Each has client ID, client secret (if confidential), allowed callback URLs, allowed scopes.
Callback URL mismatch: OAuth spec requires callback URL to exactly match what the app registered. If app registers https://app.example.com/callback but redirects to https://old-app.example.com/callback, Cognito rejects it with “redirect_uri_mismatch” error.
JWT Tokens:
- ID token: user identity (name, email, custom attributes).
- Access token: authorization (scopes: openid, profile, email, custom).
- Refresh token: obtain new access token without user re-login.
Custom claims: Add custom attributes to user pool (tenant_id, organization, role). Cognito includes these in JWT token.
API Gateway Authorizers: Token Validation
Cognito Authorizer: API Gateway validates JWT access token issued by Cognito user pool.
Process:
- Client sends Authorization header:
Authorization: Bearer <access_token>. - API Gateway authorizer validates signature (Cognito public key) and expiry.
- If valid, authorizer returns IAM policy allowing/denying access.
- API Gateway enforces policy (allow = request reaches Lambda; deny = 403 Forbidden).
Scope enforcement: OAuth scopes are claims in the access token. Authorizer validates that token has required scopes.
Example:
- Scope
api/writemeans user can POST/PUT/DELETE. - Scope
api/readmeans user can GET only. - API Gateway enforces: if request is DELETE and token only has
api/read, deny with 403.
Tenant Isolation via JWT Claims
Problem: SaaS with multiple tenants. Prevent tenant A from accessing tenant B’s data.
Solution: Cognito custom claims include tenant_id. Application validates: if user’s tenant_id claim is “acme” and they request data for tenant “widgets”, deny with 403.
Implementation:
- Cognito user pool has custom attribute
tenant_id. - Cognito includes
tenant_idin ID and access tokens. - Application reads
tenant_idfrom JWT claims. - Application filters database queries by
tenant_idin JWT (e.g.,SELECT * FROM orders WHERE tenant_id = $claims['tenant_id']). - If
tenant_idmismatch, deny access.
Critical: Enforcement must be application-side. API Gateway authorizer can’t enforce multi-tenant isolation; it only validates token format. Application must validate every request.
Comparison Table
| Component | Purpose | Notes |
|---|---|---|
| Route 53 | DNS | Manages custom domain DNS records and health checks. |
| ACM | TLS Certificates | Issues and auto-renews certificates; integrates with Route 53 for DNS validation. |
| Cognito User Pool | User Management | Stores users, handles authentication, issues JWT tokens. |
| Cognito Hosted UI | Login UI | Pre-built OAuth 2.0 login form; reduces need to build custom auth UI. |
| API Gateway Authorizer | Token Validation | Validates JWT token; enforces IAM policy (allow/deny). |
| WAF | Request Filtering | Rate limiting, IP reputation, SQL injection protection. |
Common Pitfalls
| Pitfall | Why | Fix |
|---|---|---|
| Callback URL mismatch during domain migration | OAuth redirects to wrong domain. Cognito rejects with redirect_uri_mismatch. Login fails. |
During migration: register both old and new callback URLs in app client. After migration: update all app clients to use only new URL. Test before cutover. |
| No certificate expiry monitoring | ACM auto-renews, but only if cert is being used. If cert is not in use (e.g., old domain is deprecated), renewal fails silently. | Monitor certificate status via CloudWatch event. Set SNS notification 60+ days before expiry. Test renewal in non-prod first. |
| No JWT claim validation in application | Authorizer validates token format; doesn’t validate claims. If tenant_id claim is wrong, application uses it anyway. |
Application must validate JWT claims against request context. Example: if user requests tenant_id “A” but JWT has tenant_id “B”, deny. |
| Overly broad JWT claims | Token includes all user attributes. If token is leaked, attacker has all attributes (email, phone, custom data). | Include only necessary claims. Use scopes for authorization (which APIs can be called); use claims for context (who is the user). |
| No token revocation | User is deleted/disabled, but JWT token is still valid for hours (typical token TTL is 1 hour). | Use short-lived access tokens (15-60 minutes) + refresh tokens (days/months). Maintain token revocation list for emergency scenarios. Monitor CloudTrail for disabled user’s API calls. |
| Cognito as only auth; no secondary identity provider | Cognito outage = no login possible. | Support federated login (Google, GitHub) via Cognito identity providers. Users can alternate provider if primary fails. |
| Cross-region failover not tested | Failover configuration exists but never tested. Real failure reveals unknown issues. | Test failover in staging: shut down primary Cognito region, verify secondary works. Test Route 53 health check triggering failover. |
Interview Questions
-
Design a custom-domain SaaS login for 10K users across 5 regional tenants, with zero downtime during domain migration from
login.oldco.comtologin.example.com. — Tests understanding of OAuth callback URL matching, Cognito app client configuration, gradual traffic shifting, and rollback plan. -
A user’s JWT token claims include
tenant_id: "acme", but they request data for tenantwidgets. How does your application prevent this? — Tests understanding that authorizer validates token format only; application must validate claims against request context. -
Cognito region fails. How does your system respond? What’s the RTO? — Tests multi-region failover design, Route 53 health checks, federated identity providers as alternate login, token refresh behavior.
-
Your API requires scopes
api/writefor POST andapi/readfor GET. How do you enforce this? — Tests understanding of OAuth scopes, JWT tokens, API Gateway authorizer policy, and scope validation logic.