Building a Zero-Trust Network Perimeter for S3 with Terraform
Even if IAM keys leak, attackers stay locked out. Learn how VPC Endpoints and S3 bucket policies enforce a zero-trust network perimeter in Terraform.
In a multi-AZ 3-tier web application, storing media files locally on EC2 instances is unsustainable since auto-scaling destroys uploaded data. Offloading to S3 is the standard fix, but relying on IAM permissions alone leaves the entire storage layer exposed if credentials leak.
The approach described here adds a network-level isolation layer on top of identity-based security: application servers in private subnets route traffic to S3 through a VPC Gateway Endpoint, keeping requests off the public internet entirely. A Terraform-defined S3 bucket policy explicitly denies all s3:GetObject and s3:PutObject calls unless they originate from that specific VPC Endpoint ID — meaning even a stolen IAM key becomes useless outside the VPC.
The piece also flags a common sequencing trap: applying the strict deny policy before VPC Endpoint route tables have fully propagated, or before CI/CD runners get proper exceptions, can instantly lock teams out of their own bucket, since AWS deny statements are absolute and cannot be overridden.
By combining identity and network perimeters, this pattern eliminates entire classes of credential-theft attacks — an exposed AWS key on GitHub becomes largely harmless if the attacker isn't executing code from within the designated VPC subnets.