要让 CloudFront 的权限配置真正贴合最小权限原则,第一步不是复制一段 JSON 策略,而是先拆解访问行为。只读监控、缓存刷新、配置变更、删除分发这四类动作的风险等级完全不同。一个自动刷新 CDN 缓存的 Jenkins 任务如果拥有 cloudfront:DeleteDistribution 权限,就相当于给脚本埋了一颗可以清空生产入口的定时炸弹。IAM 策略本身并不复杂,复杂的是把资源边界和条件键用对地方。CloudFront 的大部分写操作支持资源级授权,但个别列表操作只能使用 *。因此合理做法是创建多个小策略,分别绑定到不同角色,再通过资源标签或具体 ARN 收敛范围。

一、先理清 CloudFront 的操作类型和资源边界
CloudFront 的 IAM 操作以 cloudfront: 前缀开头,可以粗略分成只读、配置、缓存失效三类。只读操作包括 GetDistribution、GetDistributionConfig、ListDistributions 和 ListTagsForResource,适合绑定给监控或审计角色。配置操作中,UpdateDistribution 会改变源站、缓存行为、SSL 证书等关键字段,权限需要谨慎授予;DeleteDistribution 则必须严格限制,因为删除后需要重新部署并等待全网生效。缓存失效操作 CreateInvalidation 只负责刷新边缘节点缓存,不应和配置权限混在一起。
资源边界方面,CloudFront 分发资源的 ARN 格式为 arn:aws:cloudfront::账号ID:distribution/分发ID。大多数操作都支持对单个分发授权,例如把 CreateInvalidation 限制到某个具体 distribution ID。但 ListDistributions 这类列表操作只能写 *,因为它返回的是账号下所有分发的摘要信息。如果不想让某个角色看到全部列表,可以使用资源标签条件或直接换用只读接口组合,但不能做到完全按 distribution 过滤列表结果。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontReadOnly",
"Effect": "Allow",
"Action": [
"cloudfront:GetDistribution",
"cloudfront:GetDistributionConfig",
"cloudfront:ListDistributions",
"cloudfront:ListTagsForResource"
],
"Resource": "*"
}
]
}
这段只读策略不会开放任何修改能力,适合给需要查看分发状态但不应改配置的岗位使用。如果连查看全部列表都算越权,可以把角色直接绑定到具体分发页面,但 IAM 侧仍建议保留只读策略作为基础。
二、基于最小权限拆分三类典型策略
实际运维中更推荐把策略拆成缓存刷新、配置更新、删除操作三个独立策略,而不是写一个大而全的自定义策略。缓存刷新只需要三个操作:CreateInvalidation、GetInvalidation、ListInvalidations,并且资源可以限定到某个生产分发。下面是一个只允许对指定 ID 执行失效操作的策略。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowInvalidationOnProdDistribution",
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetInvalidation",
"cloudfront:ListInvalidations"
],
"Resource": "arn:aws:cloudfront::123456789012:distribution/E2ABC123XYZ"
}
]
}
这个策略绑定给 CI/CD 发布角色后,它只能刷新指定的 CloudFront 分发缓存,无法查看或修改分发的源站配置。即使脚本里误写了删除分发命令,也会因为缺少 DeleteDistribution 权限而被拒绝。这样可以有效缩小一次错误调用造成的影响半径。
对于需要调整源站或缓存行为的团队,可以再配置一个带资源标签条件的更新策略。先在分发的标签中加入 env=prod,然后通过 aws:ResourceTag/env 条件限制可更新的资源范围。策略如下。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUpdateTaggedDistribution",
"Effect": "Allow",
"Action": [
"cloudfront:UpdateDistribution",
"cloudfront:TagResource",
"cloudfront:UntagResource"
],
"Resource": "arn:aws:cloudfront::123456789012:distribution/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/env": "prod"
}
}
}
]
}
这里仍然允许对所有打了 env=prod 标签的分发执行更新,但不会触及未打标签的测试环境。删除权限最好不要放在日常策略中,而是单独使用 DeleteDistribution 并限定到具体 ID,同时要求 MFA 或特权角色审批。
三、CloudFront 访问 S3 源站的权限细节
如果 CloudFront 的源站是私有 S3 桶,光配置 IAM 用户策略还不够,还需要让 CloudFront 服务本身有权限读取桶对象。推荐使用 OAC(Origin Access Control)替代旧式 OAI,OAC 会在请求 S3 时携带签名信息,桶策略可以精准校验来源分发。
下面的桶策略允许 cloudfront.amazonaws.com 服务主体读取指定桶中的对象,条件是请求必须来自特定 CloudFront 分发。这样即使有人拿到了桶的普通读取权限策略,只要不是通过该分发访问,仍会被拒绝。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontOACRead",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E2ABC123XYZ"
}
}
}
]
}
这个条件键 aws:SourceArn 是 OAC 访问 S3 的关键,防止桶被任意 CloudFront 分发读取。需要注意,如果桶策略和 IAM 策略同时存在,最终权限是两者的交集。CloudFront 管理角色的 IAM 策略里可以完全不放 s3:GetObject,只保持它对 CloudFront 配置的写权限即可,对象读取交给分发凭据完成。
四、用权限边界或 SCP 框住最大权限
如果账号内有多个团队共用 CloudFront,单靠 IAM 策略可能还是会出现某个人给自己附加过宽策略的情况。此时可以使用权限边界(Permissions Boundary)限制角色能够获得的最大权限范围。例如给所有 CloudFront 运维角色设置一个边界,只允许执行 cloudfront:Get* 和 cloudfront:List*,这样即使有人尝试创建带 DeleteDistribution 的策略,边界也会兜底拒绝。
组织层面还可以配合 SCP(服务控制策略)限制成员账号不能执行某些高危操作。比如在 SCP 中拒绝 cloudfront:DeleteDistribution,只有特定豁免账号可以删除。这样双保险可以防止误操作从账号内部和外部同时穿透。最小权限不是一次性配置完就结束,需要结合 CloudTrail 日志定期审计真实调用记录,发现长期未使用的权限就及时从策略中移除。
最终目标是让每个角色只拥有答案范围内的能力:监控角色能看、发布角色能刷缓存、配置角色能改指定分发、删除角色需要额外审批。CloudFront 权限配置并不难,难在坚持按动作拆分并随业务变化持续收缩,这才是最小权限原则的落地方式。
AWS CloudFrontIAM 权限最小权限原则修改时间:2026-10-02 07:02:22