mTLS
Mutual TLS provides transport-layer client authentication for all traffic from the Amplify BFF to the Arda API Gateway, complementing the existing OAuth 2.0 authorization layer.
Network Structure
Section titled “Network Structure”- All external access enters through a single AWS HTTP API Gateway per Environment
- The API Gateway uses AWS Cognito for OAuth 2.0 user authentication
- The Arda Frontend Application consists of a React SPA in the browser and a Next.js Amplify BFF
- All private key material is stored in a dedicated OAM AWS account, separate from workload accounts
Security Objectives
Section titled “Security Objectives”- Defense in Depth — mTLS adds a second authentication layer alongside OAuth 2.0
- Zero Trust — client identity verified at the network layer before any request is processed
- Centralized Key Management — all private keys stored in the OAM account; never in workload accounts
Traffic Scope
Section titled “Traffic Scope”| Path | Authentication |
|---|---|
| Browser → Amplify | HTTPS + OAuth 2.0 |
| Amplify BFF → API Gateway | HTTPS + mTLS + OAuth 2.0 |
| Mobile App → API Gateway | Not in scope (future) |
Certificate Hierarchy
Section titled “Certificate Hierarchy”- Root CA — 10-year validity, stored in OAM Secrets Manager (
{Environment}/Arda/RootCA) - Client Certificate — 365-day validity, stored in OAM Secrets Manager (
{Environment}/NextJs/MtlsKeys)- Common Name:
{Environment}-{Application}-Client(e.g.,Prod-NextJs-Client) - Rotated automatically every 90 days via Lambda + EventBridge Scheduler
- Common Name:
- Truststore — S3 bucket in workload account containing only the Root CA public certificate
Two-Account Architecture
Section titled “Two-Account Architecture”OAM Account (Account A):
- Generates and stores Root CA and client certificates in Secrets Manager
- Hosts the rotation Lambda and EventBridge Scheduler
- Grants cross-account read access to the Amplify service role in the workload account
Workload Account (Account B):
- Hosts the API Gateway and Amplify application
- Hosts the public truststore S3 bucket (
arda-mtls-truststore-{environment}) - API Gateway uses the truststore URI to validate client certificates
Environment Strategy
Section titled “Environment Strategy”| Environment | mTLS Enabled | Certificate Naming |
|---|---|---|
| Development | Optional | Dev-NextJs-Client |
| Staging | Required | Staging-NextJs-Client |
| Production | Required | Prod-NextJs-Client |
All environments share a single OAM account but use separate secrets with environment-prefixed names.
Key Operations
Section titled “Key Operations”Initial Setup (Phase 1: OAM Account)
Section titled “Initial Setup (Phase 1: OAM Account)”# Generate Root CAopenssl genrsa -out MyRootCA.key 4096openssl req -x509 -new -nodes -key MyRootCA.key -sha256 -days 3650 -out MyRootCA.pem -subj "/CN=ArdaPrivateRootCA"
# Generate Client Certificateopenssl genrsa -out client.key 2048openssl req -new -key client.key -out client.csr -subj "/CN=Prod-NextJs-Client"openssl x509 -req -in client.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAserial MyRootCA.srl -out client.pem -days 365 -sha256Store Root CA and client certificate in Secrets Manager. Configure cross-account resource policy to allow the Amplify service role to call secretsmanager:GetSecretValue.
API Gateway Configuration (Phase 2: Workload Account)
Section titled “API Gateway Configuration (Phase 2: Workload Account)”- Upload
MyRootCA.pemtos3://arda-mtls-truststore-{environment}/MyRootCA.pem(versioning enabled, all public access blocked) - Disable the default
*.execute-api.amazonaws.comendpoint to prevent mTLS bypass - Enable mTLS on the API Gateway custom domain with the S3 truststore URI
Amplify BFF Implementation (Phase 3)
Section titled “Amplify BFF Implementation (Phase 3)”The Next.js BFF fetches the client certificate from Secrets Manager at startup and caches the https.Agent for 4 hours. On TLS errors, the agent is refreshed and the request is retried once.
Key environment variables:
OAM_REGION=us-east-1MTLS_SECRET_ARN=arn:aws:secretsmanager:us-east-1:{OAM_ACCOUNT_ID}:secret:Prod/NextJs/MtlsKeys-xxxxxxAPI_DOMAIN=api.arda.cardsAutomatic Certificate Rotation
Section titled “Automatic Certificate Rotation”A Lambda function in the OAM account runs every 90 days (EventBridge Scheduler) to:
- Read the Root CA from Secrets Manager
- Generate a new client key pair (2048-bit RSA)
- Sign a new client certificate (365-day validity)
- Update the
{Environment}/NextJs/MtlsKeyssecret
The Next.js BFF picks up the new certificate automatically via the TTL-based cache refresh — no deployment required.
Rollback Procedure
Section titled “Rollback Procedure”If mTLS enforcement causes an outage:
- Toggle mTLS OFF on the API Gateway custom domain (reverts to HTTPS-only)
- Investigate: check S3 truststore URI and certificate validity
- Re-enable after fixing configuration
Disabling mTLS is a temporary emergency measure only — it exposes the API to requests without client certificates.
Acceptance Criteria
Section titled “Acceptance Criteria”- API Gateway rejects requests without a valid client certificate (HTTP 403)
- API Gateway rejects requests from certificates signed by unknown CAs
- Amplify BFF successfully makes API calls with mTLS + OAuth
- Default
*.execute-api.amazonaws.comendpoint is inaccessible - Certificate rotation completes without service interruption
- Secrets Manager access is logged in CloudTrail
Copyright: © Arda Systems 2025-2026, All rights reserved