桶策略入门:概念、区别与为什么需要细粒度控制
做云存储的,尤其是跟对象存储打交道的同行,一定绕不开「桶策略」这个东西。我最早接触它的时候,脑子里全是问号——这玩意儿跟 IAM 策略到底什么关系? 后来踩了几个坑才彻底搞明白。
说白了,桶策略是直接挂载在存储桶(Bucket)上的一份 JSON 权限声明。它告诉 AWS(或者阿里云、腾讯云):谁,在什么条件下,能对桶里的对象做什么操作。
桶策略 vs IAM 策略:一张表说清楚
| 对比维度 | 桶策略 | IAM 策略 |
|---|---|---|
| 挂载位置 | 直接绑定到特定存储桶 | 绑定到用户、用户组或角色 |
| 作用范围 | 仅影响该桶及桶内对象 | 影响账号下所有授权资源 |
| 授权对象 | 可以授权给匿名用户、其他 AWS 账号 | 只能授权给本账号内的身份 |
| 控制粒度 | 支持路径级前缀、IP 条件、VPC 端点 | 支持更复杂的条件键和资源级控制 |
| 常见用途 | 公开读取、跨账号共享、访问日志写入 | 用户权限分工、角色临时权限 |
| 最大声明数 | 单个桶最多 20KB(JSON 文本) | 每个策略最多 6 个声明,5120 字符 |
你看这个表格就清楚了。我当年刚开始做权限配置时,总喜欢把所有权限塞到 IAM 策略里,结果发现:跨账号授权根本没法用 IAM 策略做——因为 IAM 策略只能管自己账号的人。而桶策略可以直说「允许某个外部账号的某些用户读我这个桶」。这个差异很关键。
为什么需要细粒度控制?
举个实际场景。我们公司有个数据分析部门,需要读取生产环境某个日志桶里 /logs/2024/ 这个前缀下的所有文件。但他们不能碰 /logs/2023/ 之前的归档数据。
如果只用 IAM 策略给整个桶的 s3:GetObject 权限,那他们不小心就能访问到老归档。这谁受得了?
用桶策略加上 StringLike 条件限定前缀,就能精确到路径级别。我有个客户甚至要求「只允许在工作时间 09:00-18:00 通过办公网段 VPC 端点访问」,这些都能在桶策略的 Condition 里写死。
桶策略的结构长什么样?
标准的桶策略 JSON 包含几大块:Version、Statement 数组,每个 Statement 里又有 Effect、Principal、Action、Resource、Condition。下面是一个最简单的公开读策略示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
嗯,这里要注意:Principal: "*" 代表允许所有匿名用户。如果你只想让某个特定账号访问,就得写成 Principal: { "AWS": "arn:aws:iam::123456789012:root" }。我刚开始就把 "*" 当通配符随意用,结果桶变成公开读了……还好是测试环境。
你以为的「允许」和实际的「允许」
桶策略的生效逻辑是显式允许 > 显式拒绝 > 默认拒绝。但这里有个容易踩的坑:如果同时存在 IAM 策略允许和桶策略拒绝,那么最终结果是拒绝。因为拒绝优先级最高。
我曾经有个项目,运维组给一个桶写了桶策略拒绝来自非办公 IP 的访问,但数据分析组的 IAM 策略是允许所有 s3:GetObject 的。结果数据分析组在办公区外死活下载不了文件——桶策略的拒绝直接盖过了 IAM 策略的允许。
解决方案很简单:在桶策略里把需要的条件写清楚,或者干脆把拒绝逻辑放到 IAM 策略的 NotIpAddress 条件里。优先用 IAM 策略做身份级别的条件控制,用桶策略做资源级别的边界控制。
知识体系一张图
下面这张 SVG 图概括了桶策略在整个存储权限体系中的位置和核心要素:
什么时候必须用桶策略?
- 公开访问:比如静态网站托管,桶策略要声明
Principal: "*"+s3:GetObject。 - 跨账号共享:其他账号的 IAM 用户通过你桶策略的
Principal授权后才能访问。 - VPC 端点限制:只允许通过某个 VPC 端点访问桶,这是 IAM 策略不好直接做的。
- 日志写入权限:比如启用 S3 访问日志时,目标桶需要桶策略允许源账号的
S3:PutObject。 - 对象级条件控制:按前缀、标签、加密状态等条件限制操作。
其实细粒度控制的好处远不止安全。我记得有一次,业务部门要求临时给某个第三方审计开放桶的只读权限。如果用 IAM 策略,我需要创建临时 IAM 用户、分配权限、再删除——耗时又容易遗留影子账号。而用桶策略,直接在桶上追加一条带 Principal 和 Condition(IpAddress) 的声明,审计结束后删除即可。前后 5 分钟搞定,不留残留。
嗯,这一块理解透了,后面的实操配置才能真正上手。你做权限配置时,脑子里要时刻想着:这个权限是该写在桶策略还是 IAM 策略里? 想清楚再动手,比写完了再改要快得多。