如何通过Origin Access Identity让CloudFront访问S3存储桶并限制直连
解决CloudFront OAI配置时S3桶策略的Invalid Principal错误
嘿,我看你在设置CloudFront Origin Access Identity(OAI)限制S3桶访问时,碰到了MalformedPolicy: Invalid principal in policy的错误。结合你提供的Terraform代码,主要有几个地方需要修正:
核心问题分析
- Resource路径变量错误:你策略里写的
"arn:aws:s3:::$/*"是无效的,这里的$没有正确引用你的S3桶ARN,AWS无法识别这个资源路径,这很可能是触发错误的主要原因之一。 - 权限范围过大(可选优化):你用了
s3:*的全权限,对于静态网站来说完全没必要,遵循最小权限原则能提升安全性。
修正后的完整Terraform代码
resource "aws_s3_bucket_policy" "default" { bucket = aws_s3_bucket.default.id policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCloudFrontGetObjects", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${aws_cloudfront_origin_access_identity.origin_access_identity.id}" }, "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "${aws_s3_bucket.default.arn}/*" }, { "Sid": "AllowCloudFrontListBucket", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${aws_cloudfront_origin_access_identity.origin_access_identity.id}" }, "Action": "s3:ListBucket", "Resource": "${aws_s3_bucket.default.arn}" } ] } EOF }
关键修正点说明
- Resource路径修复:把
$/*替换成${aws_s3_bucket.default.arn}/*,让Terraform自动注入正确的桶ARN,同时拆分了桶本身和桶内对象的权限(ListBucket需要桶级权限,GetObject需要对象级权限)。 - 权限缩小:只保留静态网站必需的
GetObject、GetObjectVersion和ListBucket权限,避免赋予不必要的全桶权限。 - Policy版本更新:把版本从
2008-10-17换成2012-10-17,这个版本支持更完善的IAM功能,减少潜在兼容性问题。
验证步骤
- 先确认你的
aws_cloudfront_origin_access_identity.origin_access_identity资源已经成功创建,Terraform能正确读取它的ID。 - 应用修正后的代码后,去AWS控制台的S3桶权限页面查看生成的策略,确认Principal里的OAI ARN是正确的。
- 测试访问:用CloudFront域名打开你的网站应该正常,直接访问S3桶的静态网站URL会被拒绝,说明OAI限制生效了。
内容的提问来源于stack exchange,提问作者Obivan
相关产品推荐
相关产品推荐

