From 54656d1e8cd12bd190ebc1390c48b4ae6707e543 Mon Sep 17 00:00:00 2001 From: Peter Czimmermann Date: Sat, 7 Feb 2026 23:09:09 -0800 Subject: [PATCH] feat: enforce CloudFront OAC by replacing public S3 access Replace Principal: "*" bucket policy with CloudFront service principal scoped to the distribution ARN. Enable S3 public access block and remove the unused S3 website configuration since CloudFront uses the REST endpoint with its function handling index.html rewrites. --- infrastructure/outputs.tf | 5 ----- infrastructure/s3.tf | 37 ++++++++++++++++--------------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/infrastructure/outputs.tf b/infrastructure/outputs.tf index 4f8684b..2b4b83f 100644 --- a/infrastructure/outputs.tf +++ b/infrastructure/outputs.tf @@ -3,11 +3,6 @@ output "s3_bucket_name" { value = aws_s3_bucket.main.bucket } -output "s3_bucket_website_endpoint" { - description = "Website endpoint of the S3 bucket" - value = aws_s3_bucket_website_configuration.main.website_endpoint -} - output "cloudfront_distribution_id" { description = "CloudFront distribution ID" value = aws_cloudfront_distribution.main.id diff --git a/infrastructure/s3.tf b/infrastructure/s3.tf index 3c35827..241f4fc 100644 --- a/infrastructure/s3.tf +++ b/infrastructure/s3.tf @@ -3,18 +3,6 @@ resource "aws_s3_bucket" "main" { bucket = local.domain_name } -resource "aws_s3_bucket_website_configuration" "main" { - bucket = aws_s3_bucket.main.id - - index_document { - suffix = "index.html" - } - - error_document { - key = "404.html" - } -} - resource "aws_s3_bucket_versioning" "main" { bucket = aws_s3_bucket.main.id versioning_configuration { @@ -35,10 +23,10 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "main" { resource "aws_s3_bucket_public_access_block" "main" { bucket = aws_s3_bucket.main.id - block_public_acls = false - block_public_policy = false - ignore_public_acls = false - restrict_public_buckets = false + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true } resource "aws_s3_bucket_policy" "main" { @@ -49,11 +37,18 @@ resource "aws_s3_bucket_policy" "main" { Version = "2012-10-17" Statement = [ { - Sid = "PublicReadGetObject" - Effect = "Allow" - Principal = "*" - Action = "s3:GetObject" - Resource = "${aws_s3_bucket.main.arn}/*" + Sid = "AllowCloudFrontServicePrincipal" + Effect = "Allow" + Principal = { + Service = "cloudfront.amazonaws.com" + } + Action = "s3:GetObject" + Resource = "${aws_s3_bucket.main.arn}/*" + Condition = { + StringEquals = { + "AWS:SourceArn" = aws_cloudfront_distribution.main.arn + } + } } ] })