2. 桶策略与IAM策略的区别
说到权限控制,很多人脑子里最先蹦出来的就是IAM策略。嗯,没错,IAM确实是AWS权限体系的核心。但在S3这个场景下,桶策略是另一股不可忽视的力量。这两者到底什么关系?怎么分工的?说白了,这就是我们今天要聊透的问题。
我个人习惯先画一张对比图,把抽象概念先定个位。你先看看这张图,心里有个框架,我们后面慢慢拆解。
2.1 授权模型对比:我是谁 vs 你是谁
这两种策略最本质的区别,你想想看,在于它们的授权出发点完全不同。
- IAM 策略:先看“我是谁”。策略绑定到某个主体(用户、组或角色),然后规定这个主体能做什么。它的思维是:这个人能访问哪些资源?
- 桶策略:先看“你是谁”。策略挂载在S3桶上,然后规定哪些主体可以来访问这个桶。它的思维是:这个资源允许谁进来?
我曾经帮一个团队排查权限故障,他们在IAM里给了管理员全部S3权限,但死活无法通过S3控制台上传文件。查了两小时,最后发现桶策略里有一条显式Deny,拒绝所有非加密请求——而他们在控制台上传时没有手动勾选加密选项。你看,这就是典型的资源维度和身份维度打架的例子。
2.2 语法差异与生效范围
语法上两者很像,都是JSON结构,但细节上各有侧重。我习惯用表格来对比这些差异点,看起来更清楚:
| 维度 | IAM 策略 | 桶策略 |
|---|---|---|
| 基于 | 身份维度(用户/组/角色) | 资源维度(S3桶) |
| 语法 | AWS统一JSON策略语法 | S3专用策略语法(主体需显式指定 Principal) |
| 生效范围 | 账号内所有S3桶(除非显式限制资源ARN) | 仅指定的桶及桶内对象 |
| 支持匿名 | 不支持 | 支持(Principal: "*") |
| 适用场景 | 用户/应用/服务的通用权限管理 | 桶级访问控制、静态网站托管、跨账号授权 |
| 管理粒度 | 可精细化到操作级别(如 s3:PutObject) | 同样可以精细化,但主要围绕桶和对象 |
这里有个坑,我得重点说一下:桶策略必须包含Principal字段,而IAM策略不需要。因为桶策略是挂在资源上的,资源不知道谁要访问它,必须由策略明确告诉它“允许谁进来”。IAM策略本身就是挂在身份上的,所以Principal隐式生效。
2.3 适用场景:什么时候用哪个?
我建议在实际项目中,按照以下原则来决策:
- 账号内用户/权限管理 → 优先用IAM策略。你的开发人员、运维人员,直接在IAM里分配对应的S3权限就行了。维护起来也方便,一个IAM用户换了职责,改他身上的策略就行,不需要去动每个桶。
- 桶级访问受限 → 用桶策略。比如这个桶只允许某个特定VPC来源的请求访问,或者只允许使用HTTPS的请求。这些条件用IAM策略也能做,但写在桶策略里更直接,更符合“资源的防护规则由资源自己决定”的思路。
- 跨账号访问 → 必须配合使用。IAM策略负责允许“跨账号访问”这个动作,桶策略负责允许“被跨账号访问”这个动作。缺一个都通不过。
- 匿名访问(公开桶) → 只用桶策略。IAM不支持匿名,你只能用桶策略设置Principal: "*" 来实现。
- 加密强制 (SSE-KMS 等) → 桶策略最合适。强制所有上传到这个桶的请求必须使用指定的加密方式,这就是资源自己的决定权。
2.4 权限叠加:不是覆盖,是并集
IAM策略和桶策略同时存在时,它们不是谁覆盖谁的“或”关系,而是并集关系。换句话说:
最终权限 = 主体IAM策略允许 + 桶策略允许
举个实例:
- IAM策略允许用户 alice 对桶 my-bucket 执行 s3:PutObject
- 桶策略允许用户 alice 对桶 my-bucket 执行 s3:PutObject
- 结果:alice 可以上传文件
但如果其中一个 Deny 了,那就不行:
- IAM策略允许 alice 上传
- 桶策略 Deny(拒绝)所有来自 Europe(欧洲)区域的请求
- alice 如果身处欧洲区域,上传请求会被拒绝
2.5 一个容易混淆的点:谁去评估谁?
我记得有人在社区里问过一个问题:“IAM策略和桶策略的评估顺序是什么样的?”
嗯,这里其实没有先后顺序的概念——它们是同时生效的。AWS的权限引擎在收到请求时,会同时拉起所有相关的IAM策略和桶策略,一起做逻辑运算。有点像两个并列的安检门——任何一个门没通过,你都进不去。
但从实现角度看,你可以这样理解:
- AWS 先看发起请求的IAM主体,检查它有没有对应的IAM策略允许这个操作。
- 然后看目标S3桶,检查桶策略是否允许这个操作。
- 最后合并结果:两个都得是Allow。
实际上这个过程是原子化的,但用这个思路去排查问题,更容易定位是谁在拦路。
2.6 避坑指南:我见过最典型的几种翻车案例
这些年我帮别人排查S3权限故障,发现几个反复出现的坑。我直接列出来,你遇到了可以参照排查:
- IAM策略允许,桶策略默认Deny:新创建的桶,默认桶策略是“拒绝所有”。你必须在桶策略中明确写Allow,或者写一个公开策略。很多人只配了IAM策略,忘了桶策略,然后就卡住了。
- 桶策略中Principal忘记指定:写了个允许的Action和Resource,但没写Principal是谁。结果策略直接不生效,因为S3不知道你要允许谁访问。
- 跨账号访问只配了IAM策略:跨账号场景下,IAM策略和桶策略缺一不可。我见过有人只配了IAM侧的AssumeRole,桶策略没配,结果一直报403。
- Deny规则写在桶策略里,且优先级被忽视:上面说了,只要有一个Deny匹配,其他Allow全白搭。很多人给IAM配了最高权限,结果桶策略里某条Deny没注意,排查半天。
2.7 安全视角:实战建议
作为云计算安全专家,我给你几个实战中我一直在用的原则:
- 最小权限优先:不管用IAM还是桶策略,永远从“什么都不能做”开始,再逐步放开。
- 桶策略做“边界防守”:用来控制网络来源、加密条件、跨账号访问等资源级别的安全规则。
- IAM策略做“内部管理”:用来控制用户、角色对桶的通用操作权限。
- 定期用IAM Access Analyzer 扫描桶策略:看看有没有公开的桶或者异常的跨账号访问权限。
- 日志要开着:开启S3服务器的访问日志,配合CloudTrail,一旦权限出问题,可以追溯是谁、在什么时候、通过什么策略访问的。
好了,这章的内容就到这了。你现在应该对桶策略和IAM策略的关系有了清晰的理解。两种策略不是二选一,而是配合使用——你用它们各自的长处,去构建一个既安全又灵活的S3权限体系。下一张图我们就要进入实战了,准备好动手写第一个桶策略吧。