You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除CloudFront OAI后S3桶策略异常引发报错,如何规避?

问题背景

我有一个配置了如下策略的S3桶:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "EB73SOC545AIK",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EB73SOC545AIK"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mybucket-app-dev-bucket/*"
        }
    ]
}

删除关联该OAI(EB73SOC545AIK)的CloudFront分发后,桶策略被自动修改为如下畸形策略:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "EB73SOC545AIK",
            "Effect": "Allow",
            "Principal": {
                "AWS": "AIDAIHJ7YKCENOC6XHCIQ"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mybucket-app-dev-bucket/*"
        }
    ]
}

后续用boto3追加新策略语句时(代码如下),触发MalformedPolicy错误,初期误以为是新语句问题,排查耗时:

client = boto3.client('s3')
pol = client.get_bucket_policy(Bucket=bucket)['Policy']
pol = json.loads(pol)
pol['Statement'].append(....)
client.put_bucket_policy(
    Bucket=bucket,
    Policy=json.dumps(bucket_policy)
)

请问该如何规避这一问题?

规避方案

1. 提前清理失效OAI关联策略

删除CloudFront分发前,手动移除S3桶中对应OAI的策略语句,避免AWS自动将OAI ARN替换成无效的纯IAM用户ID(如AIDAIHJ7YKCENOC6XHCIQ)。

2. 修复已存在的畸形策略

如果已经出现畸形策略,可通过代码过滤掉Principal为纯IAM用户ID的失效语句:

import json
import boto3

client = boto3.client('s3')
bucket = "mybucket-app-dev-bucket"

# 获取并解析现有桶策略
policy_str = client.get_bucket_policy(Bucket=bucket)['Policy']
policy = json.loads(policy_str)

# 过滤无效的OAI策略语句
valid_statements = []
for stmt in policy['Statement']:
    principal = stmt.get('Principal', {}).get('AWS')
    # 有效CloudFront OAI的ARN格式以arn:aws:iam::cloudfront:user/开头
    if isinstance(principal, str):
        if principal.startswith('arn:aws:iam::cloudfront:user/'):
            valid_statements.append(stmt)
    elif isinstance(principal, list):
        # 处理多Principal场景
        valid_principals = [p for p in principal if p.startswith('arn:aws:iam::cloudfront:user/')]
        if valid_principals:
            stmt['Principal']['AWS'] = valid_principals
            valid_statements.append(stmt)

policy['Statement'] = valid_statements

# 重新设置合法的桶策略
client.put_bucket_policy(
    Bucket=bucket,
    Policy=json.dumps(policy)
)

3. 追加策略前做合法性校验

在追加新策略语句前,先校验现有策略的完整性:

  • 检查所有Principal.AWS是否为有效ARN格式,而非纯用户ID
  • 可调用S3的validate_policy API提前验证策略格式(需额外权限):
# 提前验证策略合法性
validation = client.validate_policy(
    PolicyDocument=json.dumps(policy)
)
if validation['IsValid']:
    client.put_bucket_policy(Bucket=bucket, Policy=json.dumps(policy))
else:
    print(f"策略无效: {validation['ValidationErrors']}")

4. 手动管理策略,避免依赖AWS自动修改

不要依赖AWS在删除CloudFront分发时自动调整S3桶策略,建议用Terraform、CloudFormation等基础设施即代码工具维护桶策略,确保策略变更可追溯、可控制。

内容的提问来源于stack exchange,提问作者santos82h

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:43:23