Encryption in transit
Load balancer TLS policies and where TLS terminates, mutual TLS, ACM and AWS Private CA across Regions, CloudFront protocol policies, inter-node encryption for EMR, EKS and SageMaker AI, Nitro encryption, and forcing TLS on AWS APIs.
Exam tasks: 5.1.1 (require encryption: load balancer security policies, TLS), 5.1.2 (secure private access, covered in Hybrid and private access), 5.1.3 (inter-resource encryption: EMR, EKS, SageMaker AI, Nitro), 5.3.5 (certificates across one or many Regions)
The decision: on every hop between a client and your data, where is TLS terminated, who holds the private key, which protocol versions are allowed, and how do you prove nothing travels in cleartext?
Where TLS ends
| Pattern | Listener | Certificate lives on | Load balancer sees plaintext | Use when |
|---|---|---|---|---|
| Terminate | ALB HTTPS or NLB TLS, HTTP/TCP to targets | Load balancer (ACM) | Yes | Internal hop is trusted, and you want offload |
| Re-encrypt | ALB HTTPS to HTTPS targets, NLB TLS to TLS targets | LB and targets | Yes, briefly | Compliance needs encryption on every hop, and you still want WAF or routing |
| Passthrough | NLB TCP 443 to targets | Targets only | No | Key must never leave your servers, or the target does its own mTLS |
- An ALB doesn't validate the certificate on HTTPS targets, so self-signed or Private CA certificates on the targets are fine.
- With passthrough, the load balancer can't add
X-Forwarded-Foror run AWS WAF, and ACM certificates can't be installed on the instances (unless you use an exportable ACM certificate or AWS Private CA).
Load balancer security policies
A security policy fixes the TLS versions and cipher suites the load balancer negotiates with clients.
| Policy family | Allows | Pick it for |
|---|---|---|
ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 | TLS 1.3 and 1.2, forward-secret ciphers, hybrid post-quantum key exchange | Console default and the AWS recommendation |
ELBSecurityPolicy-TLS13-1-2-2021-06 | TLS 1.3 and 1.2 | Broad compatibility without legacy protocols |
ELBSecurityPolicy-TLS13-1-3-2021-06 (and -PQ- variants) | TLS 1.3 only | "Only TLS 1.3" requirements |
...-FIPS-... | FIPS-validated cryptographic modules | FedRAMP and FIPS 140 requirements |
...-RFC9151-... | CNSA 1.0 suites | US national security workloads |
ELBSecurityPolicy-2016-08 | Down to TLS 1.0 | Default for CLI, CloudFormation and CDK, so always set a policy explicitly |
- Forward secrecy (FS/PFS): every TLS 1.3 policy provides it, and so do TLS 1.2 policies limited to ECDHE ciphers. A stolen private key then can't decrypt previously recorded sessions.
- ALB doesn't support custom policies; pick a predefined one. The policy for the ALB-to-target leg is derived from the listener policy, not chosen separately.
- Restrict which policies teams may choose with the
elasticloadbalancing:SecurityPolicycondition key in an SCP or IAM policy. - Enable connection logs on the ALB to see the negotiated TLS version and cipher per connection before you tighten a policy.
The default you didn't choose
A listener created with CloudFormation or the CLI without SslPolicy gets ELBSecurityPolicy-2016-08, which
still allows TLS 1.0 and 1.1. When a scan finds "TLS 1.0 enabled on the load balancer" in an IaC-built stack, the
fix is to set a TLS 1.2+ policy on the listener, not to rotate the certificate.
SNI and multiple certificates
- ALB and NLB TLS listeners accept multiple certificates, and choose one per connection by the SNI host name
the client sends. One listener can serve
shop.example.comandapi.example.org. - CloudFront serves custom certificates with SNI by default. A dedicated-IP option exists only for very old clients that don't send SNI.
Mutual TLS
| Where | How it works |
|---|---|
| ALB, verify mode | Upload a CA bundle as a trust store (from S3), optionally with CRLs. The ALB rejects clients without a valid certificate and passes certificate details to targets in headers |
| ALB, passthrough mode | The ALB forwards the client's certificate chain in the X-Amzn-Mtls-Clientcert header, and your application verifies it |
| API Gateway | Custom domain with a truststore in S3. Disable the default execute-api endpoint so clients can't skip mTLS |
| NLB TCP passthrough | The target terminates TLS and verifies client certificates itself |
Private CA is the usual issuer for client certificates on devices, partner systems and internal services.
ACM certificates
- Regional: a certificate works only in the Region where it was issued or imported. CloudFront needs its certificate in us-east-1.
- Public certificates are issued with a validity of 198 days (the CA/Browser Forum maximum dropped to 200 days in March 2026). DNS-validated certificates renew automatically, starting 45 days before expiry, as long as the CNAME record stays in place.
- Imported certificates never renew automatically. ACM sends expiry events to EventBridge, and the AWS Config
rule
acm-certificate-expiration-checkflags them. - Exportable public certificates can be installed on EC2, containers or on-premises servers, at a per-certificate charge. Standard ACM public certificates can't be exported.
- Private certificates requested through ACM from your Private CA renew automatically when ACM manages them.
AWS Private CA
- A CA is a Regional resource and can't be copied. For several Regions, create a subordinate CA in each Region and have one root sign all of them, so every client trusts a single root.
- Keep the root CA for signing subordinates only, and restrict
acm-pca:IssueCertificateon it tightly. - Share CAs across accounts with AWS RAM so workload accounts can request certificates without owning a CA.
- General-purpose mode issues certificates of any validity and supports CRL and OCSP revocation. Short-lived certificate mode issues certificates valid for up to 7 days at lower cost; they expire before revocation matters.
- Integrations: ACM (managed renewal for ELB, CloudFront, API Gateway), EKS through the cert-manager
aws-privateca-issuer, Connector for AD (Windows auto-enrolment), Connector for SCEP (mobile devices).
Exam signal
"Internal services need TLS certificates that renew automatically and are trusted only inside the company" is AWS Private CA with ACM-managed private certificates. "Browsers on the internet must trust it" is an ACM public certificate. A self-signed certificate is never the best answer.
CloudFront
| Setting | Options | Secure choice |
|---|---|---|
| Viewer protocol policy (per behaviour) | HTTP and HTTPS, Redirect HTTP to HTTPS, HTTPS only | Redirect or HTTPS only |
| Viewer security policy | Minimum TLS version for viewers | TLSv1.2_2021 or newer |
| Origin protocol policy (custom origins) | HTTP only, HTTPS only, Match viewer | HTTPS only |
| Origin SSL protocols | TLS versions to the origin | TLS 1.2 |
- The origin's certificate must be valid and match the origin domain name (or the Host header you forward). CloudFront won't connect to an origin with a self-signed certificate.
- An S3 website endpoint only speaks HTTP. For HTTPS end to end, use the S3 REST endpoint with origin access control (OAC), which also works with SSE-KMS buckets.
- Field-level encryption encrypts chosen POST form fields (up to 10) at the edge with a public key you upload. Only the component holding the private key, deep in your stack, can read them, so intermediate services and logs only see ciphertext.
Encryption between nodes and resources
| Service | How to encrypt node-to-node traffic |
|---|---|
| Amazon EMR | A security configuration with in-transit encryption: EMR-managed certificates, a PEM zip in S3, or a custom certificate provider. It turns on TLS and SASL for the open-source frameworks. At-rest settings (EMRFS SSE-KMS or CSE-KMS, local disk and EBS encryption) sit in the same security configuration |
| Amazon EKS | Pod-to-pod over Nitro instances that encrypt automatically, or a service mesh with mTLS, or VPC Lattice with TLS. Kubernetes API data (including Secrets) is envelope-encrypted with KMS by default on 1.28+, optionally with your own key |
| SageMaker AI | EnableInterContainerTrafficEncryption on training and tuning jobs. It uses IPsec, so the security group must allow UDP 500 and protocol 50 (ESP) to itself. Costs some training time |
| Amazon OpenSearch Service | Node-to-node encryption plus "require HTTPS" on the domain endpoint |
| ElastiCache, MSK, Redshift, RDS | Enable in-transit encryption (ElastiCache, MSK), set require_ssl (Redshift), or rds.force_ssl / require_secure_transport (RDS engines) |
Nitro encryption and VPC Encryption Controls
- Modern Nitro instance types encrypt traffic between each other automatically with AES-256, at no cost to performance, when both are in the same VPC or peered VPCs.
- That automatic encryption doesn't cover traffic through a load balancer, transit gateway or other intermediary, or traffic to older instance types.
- VPC Encryption Controls give proof and enforcement. Monitor mode adds an
encryption-statusfield to new VPC flow logs and lists resources that allow cleartext. Enforce mode blocks resources that can't encrypt (older instances, internet gateways) unless you create an exclusion. Transit gateways need encryption support turned on to carry encrypted traffic between enforced VPCs.
Forcing TLS on AWS APIs and data stores
{
"Sid": "DenyWithoutTls",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::orders-archive-7731", "arn:aws:s3:::orders-archive-7731/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}- Put the same deny on SQS queue policies, SNS topic policies and EFS file system policies.
- Use
s3:TlsVersion(numeric condition) to require a minimum version, for example a deny whens3:TlsVersionisNumericLessThan1.3 for a TLS 1.3-only bucket. - AWS service API endpoints already require TLS 1.2 or later.
- Hybrid links: Site-to-Site VPN (IPsec) or MACsec on dedicated Direct Connect connections. See Hybrid and private access.
Scenarios
Re-encryption keeps both hops encrypted and still lets the ALB run WAF and path routing. An NLB TCP passthrough is encrypted end to end but can't do WAF or path routing. HTTP to targets leaves the inner hop in cleartext, even in private subnets. An NLB TLS listener with TCP targets also sends plaintext to the instances.
The listener picked up the CLI and CloudFormation default policy, which allows TLS 1.0. Setting a TLS 1.2+ policy fixes it in place, and the chosen policy offers only forward-secret ciphers. The certificate doesn't control protocol versions. WAF inspects HTTP requests after the TLS handshake, so it can't block old protocols. Adding CloudFront is far more work and leaves the ALB itself unchanged.
Inter-container traffic encryption uses IPsec, so the job flag and the IKE and ESP security group rules are both needed. The volume KMS key encrypts storage, not network traffic. Network isolation blocks outbound calls but doesn't encrypt traffic between nodes. A VPC endpoint secures API calls to SageMaker, not container-to-container traffic.
Further reading
Key material and HSMs
Imported versus KMS-generated key material, rotating and expiring imported keys, CloudHSM clusters, and KMS custom key stores backed by CloudHSM or an external key manager.
S3 data protection
S3 encryption options and how to enforce a specific key, Bucket Keys, SSE-KMS permissions for multipart uploads, public access and ownership controls, VPC endpoint policies, versioning, MFA delete, Object Lock, Glacier Vault Lock and lifecycle retention.