2. 桶策略与IAM策略的区别

说到权限控制,很多人脑子里最先蹦出来的就是IAM策略。嗯,没错,IAM确实是AWS权限体系的核心。但在S3这个场景下,桶策略是另一股不可忽视的力量。这两者到底什么关系?怎么分工的?说白了,这就是我们今天要聊透的问题。

我个人习惯先画一张对比图,把抽象概念先定个位。你先看看这张图,心里有个框架,我们后面慢慢拆解。

桶策略 vs IAM 策略:核心比较 IAM 策略 授权模型:身份维度 绑定主体(用户/组/角色) 语法统一,支持所有AWS服务 生效范围:账号内所有资源 可跨账号委托(角色) 桶策略 授权模型:资源维度 直接附加到S3桶 S3专用JSON语法 生效范围:仅该桶及桶内对象 可授予匿名/跨账号访问 并集叠加,缺一不可? 优先级关键点 AWS先评估IAM策略,再评估桶策略 权限 = IAM策略允许 ∩ 桶策略允许 IAM 用户授权 控制台/CLI访问 IAM 角色授权 跨账号/EC2承担 桶策略资源授权 匿名/特定账号 桶策略加密强制 拒绝非加密请求

2.1 授权模型对比:我是谁 vs 你是谁

这两种策略最本质的区别,你想想看,在于它们的授权出发点完全不同。

  • IAM 策略:先看“我是谁”。策略绑定到某个主体(用户、组或角色),然后规定这个主体能做什么。它的思维是:这个人能访问哪些资源?
  • 桶策略:先看“你是谁”。策略挂载在S3桶上,然后规定哪些主体可以来访问这个桶。它的思维是:这个资源允许谁进来?

我曾经帮一个团队排查权限故障,他们在IAM里给了管理员全部S3权限,但死活无法通过S3控制台上传文件。查了两小时,最后发现桶策略里有一条显式Deny,拒绝所有非加密请求——而他们在控制台上传时没有手动勾选加密选项。你看,这就是典型的资源维度和身份维度打架的例子。

一句话记住:IAM策略是“出门证”,桶策略是“门禁系统”。两个都得放行,你才能进去。

2.2 语法差异与生效范围

语法上两者很像,都是JSON结构,但细节上各有侧重。我习惯用表格来对比这些差异点,看起来更清楚:

维度 IAM 策略 桶策略
基于 身份维度(用户/组/角色) 资源维度(S3桶)
语法 AWS统一JSON策略语法 S3专用策略语法(主体需显式指定 Principal)
生效范围 账号内所有S3桶(除非显式限制资源ARN) 仅指定的桶及桶内对象
支持匿名 不支持 支持(Principal: "*")
适用场景 用户/应用/服务的通用权限管理 桶级访问控制、静态网站托管、跨账号授权
管理粒度 可精细化到操作级别(如 s3:PutObject) 同样可以精细化,但主要围绕桶和对象

这里有个坑,我得重点说一下:桶策略必须包含Principal字段,而IAM策略不需要。因为桶策略是挂在资源上的,资源不知道谁要访问它,必须由策略明确告诉它“允许谁进来”。IAM策略本身就是挂在身份上的,所以Principal隐式生效。

2.3 适用场景:什么时候用哪个?

我建议在实际项目中,按照以下原则来决策:

  1. 账号内用户/权限管理 → 优先用IAM策略。你的开发人员、运维人员,直接在IAM里分配对应的S3权限就行了。维护起来也方便,一个IAM用户换了职责,改他身上的策略就行,不需要去动每个桶。
  2. 桶级访问受限 → 用桶策略。比如这个桶只允许某个特定VPC来源的请求访问,或者只允许使用HTTPS的请求。这些条件用IAM策略也能做,但写在桶策略里更直接,更符合“资源的防护规则由资源自己决定”的思路。
  3. 跨账号访问 → 必须配合使用。IAM策略负责允许“跨账号访问”这个动作,桶策略负责允许“被跨账号访问”这个动作。缺一个都通不过。
  4. 匿名访问(公开桶) → 只用桶策略。IAM不支持匿名,你只能用桶策略设置Principal: "*" 来实现。
  5. 加密强制 (SSE-KMS 等) → 桶策略最合适。强制所有上传到这个桶的请求必须使用指定的加密方式,这就是资源自己的决定权。
我的经验:如果权限规则只跟某个特定的S3桶有关,不涉及其他服务,我一般优先写在桶策略里。这样将来有人问“这个桶的访问规则是什么”,直接看桶策略一目了然,不用去IAM里翻一大堆策略。说白了,就是就近管理原则。

2.4 权限叠加:不是覆盖,是并集

IAM策略和桶策略同时存在时,它们不是谁覆盖谁的“或”关系,而是并集关系。换句话说:

最终权限 = 主体IAM策略允许 + 桶策略允许

举个实例:

  • IAM策略允许用户 alice 对桶 my-bucket 执行 s3:PutObject
  • 桶策略允许用户 alice 对桶 my-bucket 执行 s3:PutObject
  • 结果:alice 可以上传文件

但如果其中一个 Deny 了,那就不行:

  • IAM策略允许 alice 上传
  • 桶策略 Deny(拒绝)所有来自 Europe(欧洲)区域的请求
  • alice 如果身处欧洲区域,上传请求会被拒绝
安全底线别忘了:只要任何一个策略显式Deny,最终结果就是Deny。AWS的权限评估逻辑是“先检查所有Allow,再检查所有Deny,如果有任何一条Deny匹配,直接拒绝”。这就是为什么你给IAM配了完全的S3权限,但桶策略里一个不小心写了个Deny,你就可能什么都做不了。

2.5 一个容易混淆的点:谁去评估谁?

我记得有人在社区里问过一个问题:“IAM策略和桶策略的评估顺序是什么样的?”

嗯,这里其实没有先后顺序的概念——它们是同时生效的。AWS的权限引擎在收到请求时,会同时拉起所有相关的IAM策略和桶策略,一起做逻辑运算。有点像两个并列的安检门——任何一个门没通过,你都进不去。

但从实现角度看,你可以这样理解:

  1. AWS 先看发起请求的IAM主体,检查它有没有对应的IAM策略允许这个操作。
  2. 然后看目标S3桶,检查桶策略是否允许这个操作。
  3. 最后合并结果:两个都得是Allow。

实际上这个过程是原子化的,但用这个思路去排查问题,更容易定位是谁在拦路。

2.6 避坑指南:我见过最典型的几种翻车案例

这些年我帮别人排查S3权限故障,发现几个反复出现的坑。我直接列出来,你遇到了可以参照排查:

  1. IAM策略允许,桶策略默认Deny:新创建的桶,默认桶策略是“拒绝所有”。你必须在桶策略中明确写Allow,或者写一个公开策略。很多人只配了IAM策略,忘了桶策略,然后就卡住了。
  2. 桶策略中Principal忘记指定:写了个允许的Action和Resource,但没写Principal是谁。结果策略直接不生效,因为S3不知道你要允许谁访问。
  3. 跨账号访问只配了IAM策略:跨账号场景下,IAM策略和桶策略缺一不可。我见过有人只配了IAM侧的AssumeRole,桶策略没配,结果一直报403。
  4. Deny规则写在桶策略里,且优先级被忽视:上面说了,只要有一个Deny匹配,其他Allow全白搭。很多人给IAM配了最高权限,结果桶策略里某条Deny没注意,排查半天。

2.7 安全视角:实战建议

作为云计算安全专家,我给你几个实战中我一直在用的原则:

  • 最小权限优先:不管用IAM还是桶策略,永远从“什么都不能做”开始,再逐步放开。
  • 桶策略做“边界防守”:用来控制网络来源、加密条件、跨账号访问等资源级别的安全规则。
  • IAM策略做“内部管理”:用来控制用户、角色对桶的通用操作权限。
  • 定期用IAM Access Analyzer 扫描桶策略:看看有没有公开的桶或者异常的跨账号访问权限。
  • 日志要开着:开启S3服务器的访问日志,配合CloudTrail,一旦权限出问题,可以追溯是谁、在什么时候、通过什么策略访问的。

好了,这章的内容就到这了。你现在应该对桶策略和IAM策略的关系有了清晰的理解。两种策略不是二选一,而是配合使用——你用它们各自的长处,去构建一个既安全又灵活的S3权限体系。下一张图我们就要进入实战了,准备好动手写第一个桶策略吧。