Network and encryption
How traffic is segmented and inspected, and how data is encrypted at rest and in transit — the two policies that determine most of a workload's exposure.
Network security policy
The standard. VPC segmentation and traffic control — security groups between the internet and the VPC, between workloads, NACLs at the subnet boundary — plus the data encryption policy applied across projects.
VPC design
VPC 10.0.0.0/16
├── public-a 10.0.1.0/24 ── load balancer, NAT gateway
├── public-b 10.0.2.0/24
├── private-a 10.0.11.0/24 ── application
├── private-b 10.0.12.0/24
├── data-a 10.0.21.0/24 ── databases
└── data-b 10.0.22.0/24
| Rule | Reason |
|---|---|
| Minimum two Availability Zones | A single-AZ design fails on an AZ event |
| Workloads with no internet requirement in private subnets | Removes the primary exposure path |
| Data subnets have no route to the internet | Even via NAT |
| Separate route tables per tier | Prevents accidental transit between tiers |
| NAT gateways one per AZ | A single NAT gateway is a cross-AZ dependency and a cost and availability risk |
Security groups
Security groups are the primary control. Rules are least-privilege and reference other security groups, not CIDR blocks, wherever possible.
| Tier | Inbound | Outbound |
|---|---|---|
| ALB | 443 from 0.0.0.0/0; 80 from 0.0.0.0/0 redirecting to 443 | Application SG on the application port |
| Application | Application port from ALB SG only | Data SG on the database port; HTTPS to approved endpoints |
| Data | Database port from application SG only | None required |
resource "aws_security_group_rule" "app_from_alb" {
type = "ingress"
from_port = 8080
to_port = 8080
protocol = "tcp"
security_group_id = aws_security_group.app.id
source_security_group_id = aws_security_group.alb.id
}
Never 0.0.0.0/0 on a database port. Never 0.0.0.0/0 on SSH. Use Session
Manager instead.
Network ACLs
NACLs are stateless and subnet-level. Use them as a coarse, explicit backstop:
- Default-deny inbound on data subnets, with explicit allows from application subnet ranges.
- Deny explicit known-bad ranges at the edge.
- Ephemeral port ranges allowed for return traffic.
- Every rule numbered with room to insert; every rule documented.
NACLs are not a substitute for security groups — they are a second, independent layer.
VPC endpoints
Traffic to AWS services should not leave the VPC where it does not have to.
| Endpoint type | Use |
|---|---|
| Gateway endpoint | S3, DynamoDB — no hourly charge |
| Interface endpoint | ECR, CloudWatch Logs, Secrets Manager, SSM, KMS, STS |
Endpoint policies restrict which buckets, repositories or secrets are reachable through the endpoint, narrowing the path further.
Flow logs
- Enabled on every VPC, delivering to a central bucket.
- Retention set to meet the compliance requirement; one week is a diagnostic window, not an audit record.
- Rejected traffic reviewed; an internal host being denied repeatedly is a signal.
Egress
- Default-deny egress from application subnets to the internet.
- Approved external integrations reached through a fixed set of endpoints.
- AWS Network Firewall or a NAT with domain allow-listing where the workload has no legitimate general internet requirement.
- DNS resolution through Route 53 Resolver with DNS Firewall.
Data encryption policy
The standard. A single encryption policy across projects: how public endpoints are protected, how outbound requests are secured, and how data is encrypted at rest with keys managed centrally.
In transit
| Path | Control |
|---|---|
| Client → CloudFront / ALB | TLS 1.2+; certificates in ACM; HTTP redirected to HTTPS; HSTS |
| ALB → application | TLS where the application supports it; private network otherwise |
| Application → RDS | TLS required; rds.force_ssl enabled |
| Application → ElastiCache | TLS enabled |
| Application → S3 / DynamoDB | HTTPS to the regional endpoint, ideally via a VPC endpoint |
| Application → third-party API | TLS 1.2+ with certificate validation; no --insecure |
| Internal service → service | mTLS or service mesh where the workload requires identity-based auth |
| Administrative access | Session Manager over TLS; no direct SSH |
At rest
| Service | Encryption | Key |
|---|---|---|
| S3 | SSE-KMS | Customer-managed key per classification |
| EBS | Encrypted by default | Account default KMS key |
| RDS / Aurora | KMS | Per-workload key |
| DynamoDB | KMS | Per-workload key |
| ElastiCache | At-rest encryption | Per-workload key |
| EFS | KMS | Per-workload key |
| CloudWatch Logs | KMS | Log-specific key |
| SQS / SNS | KMS | Per-workload key |
| Backups | KMS | Backup key; cross-region replica encrypted |
| Secrets | KMS | Secrets-specific key |
Key management
- Keys are per classification and per service boundary, not one key for everything.
- Key policy separates administration from use:
{
"Sid": "AllowKeyAdministration",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<account>:role/key-admin"},
"Action": ["kms:Create*", "kms:Describe*", "kms:Enable*", "kms:Put*", "kms:Update*"],
"Resource": "*"
},
{
"Sid": "AllowKeyUsage",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<account>:role/app-role"},
"Action": ["kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "*",
"Condition": {
"StringEquals": {"kms:ViaService": "s3.us-east-1.amazonaws.com"}
}
}
- Automatic rotation enabled where supported.
- Deletion requires a waiting period and raises an alarm.
- Cross-account access uses grants, not broad key policies.
- Key usage is logged in CloudTrail and reviewed.
Data classification
| Classification | Examples | Encryption | Access |
|---|---|---|---|
| Public | Marketing content | At rest and in transit | Open |
| Internal | Internal reports | At rest and in transit | Staff |
| Confidential | Customer records, billing | Customer-managed KMS key | Named roles |
| Restricted | Payment data, health data, credentials | Dedicated key, restricted key policy | Minimal named roles, audited |
Evidence
- VPC and subnet diagram with route tables.
- Security group rules export.
- NACL configuration.
- VPC Flow Logs and endpoint configuration.
- Encryption configuration per service.
- Key policy and rotation settings.
- TLS policy on every public listener.