4. S3跨账户共享实战
假设团队 A(账户 1111-2222-3333)需要把位于 ap-northeast-1 的 S3 存储桶 team-a-dataset-prod 中的数据集共享给团队 B(账户 4444-5555-6666)。团队 B 的成员使用 IAM 角色 DataAnalystRole 访问,并且只允许读取 shared/ 前缀下的对象。本节围绕这个端到端任务,说明存储桶策略、ACL、Access Points 与跨账户复制四种机制各自解决什么问题、如何组合使用,以及如何验证共享是否真正生效。
先明确共享边界与访问路径
跨账户共享的本质是:资源所有者(团队 A)在资源侧授予权限,请求方(团队 B)在身份侧获得调用权限,两者同时满足才允许访问。因此,团队 B 的角色策略必须允许 s3:GetObject 和 s3:ListBucket,团队 A 的存储桶策略必须显式允许该角色访问。只配置一边,请求会返回 AccessDenied。
共享范围建议按前缀收敛。团队 A 只开放 shared/,不开放整个桶;团队 B 只申请读取,不申请写入或删除。这样即使后续策略被误改,影响面也可控。
存储桶策略:最直接的资源侧授权
存储桶策略是跨账户共享的首选方式,因为它把授权写在资源上,团队 B 不需要团队 A 的凭证。下面是一份可直接参考的策略示例,只允许团队 B 的角色读取 shared/ 前缀:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowTeamBListSharedPrefix",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::4444-5555-6666:role/DataAnalystRole"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::team-a-dataset-prod",
"Condition": {
"StringLike": {
"s3:prefix": "shared/*"
}
}
},
{
"Sid": "AllowTeamBReadSharedObjects",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::4444-5555-6666:role/DataAnalystRole"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::team-a-dataset-prod/shared/*"
}
]
}
注意 ListBucket 作用于桶本身,GetObject 作用于对象 ARN,两者资源写法不同。条件键 s3:prefix 用于限制列举范围,避免团队 B 看到 private/ 下的对象名。团队 B 侧的角色策略也要允许对应动作,否则即使桶策略放行,请求仍会被身份策略拦截。
ACL:理解它,但不要依赖它
ACL 是 S3 早期的访问控制机制,可以给其他账户授予读或写权限。但在启用“存储桶所有者强制”或对象所有权为“桶所有者”的桶中,ACL 默认被禁用,且新桶通常不再使用 ACL。跨账户共享时,ACL 无法表达前缀级条件,也无法限制到具体角色,粒度粗、审计困难。因此本节的做法是:保持 ACL 关闭,统一用存储桶策略或 Access Point 策略授权。只有在维护遗留系统、且确认桶未启用桶所有者强制时,才考虑 ACL,并把它当作过渡手段。
Access Points:把共享策略从桶上解耦
当多个团队需要不同权限、不同前缀时,把所有规则堆在一个桶策略里会越来越难维护。Access Point 为每个访问场景提供独立入口和独立策略。团队 A 可以创建一个名为 team-a-shared-ap 的 Access Point,绑定到 team-a-dataset-prod,并在 AP 策略中只允许团队 B 的角色读取 shared/*。团队 B 访问时使用 AP 别名或 ARN,而不是直接使用桶名。
aws s3 cp s3://team-a-shared-ap/shared/dataset-2024.csv ./dataset-2024.csv
# 或使用 AP ARN
aws s3api get-object \
--bucket arn:aws:s3:ap-northeast-1:1111-2222-3333:accesspoint/team-a-shared-ap \
--key shared/dataset-2024.csv \
./dataset-2024.csv
使用 Access Point 后,桶策略可以保持简洁,甚至只保留必要的管理权限;共享规则集中在 AP 策略中,便于按团队、按用途审计和回收。需要注意,AP 有独立的 ARN 和访问域名,团队 B 的 IAM 策略中也要允许访问该 AP 资源。
跨账户复制:把数据搬到对方账户
如果团队 B 需要高频读取、低延迟访问,或者不希望每次读取都跨账户请求,可以配置跨账户复制。复制由源桶发起,把对象异步复制到团队 B 账户的目标桶 team-b-analytics-copy。复制要求源桶和目标桶都开启版本控制,并创建一个复制角色,该角色需要读取源桶、写入目标桶,且目标桶策略要允许复制角色写入。
复制规则可以按前缀过滤,例如只复制 shared/ 下的对象,并可选更改目标存储类别。复制是异步的,通常秒级到分钟级完成;对于已有对象,需要启用批量复制或 S3 Batch Operations 回填。复制完成后,团队 B 直接读取本地桶,不再依赖团队 A 的在线授权,但数据副本的时效性和一致性需要额外管理。
验证共享是否生效
配置完成后,用团队 B 的角色执行以下检查,逐项确认权限边界:
- 列举共享前缀:
aws s3 ls s3://team-a-shared-ap/shared/,应返回对象列表。 - 读取对象:
aws s3 cp s3://team-a-shared-ap/shared/dataset-2024.csv .,应成功下载。 - 越界读取:尝试读取
private/下对象,应返回AccessDenied。 - 写入测试:尝试向共享前缀写入,应被拒绝,确认只读边界。
- 复制验证:在目标桶查看对象是否出现,并核对 ETag 或对象大小。
AccessDenied 通常是资源策略或身份策略缺失;NoSuchBucket 可能是桶名或区域写错;PermanentRedirect 说明请求发到了错误区域。用 CloudTrail 查看 GetObject 事件的 errorCode 和 requestParameters,可以快速定位是哪一侧策略拦截。Principal: "*" 且不加条件。跨账户共享必须明确指定对方账户或角色 ARN,并尽量用前缀、VPC 端点、来源 IP 等条件收窄范围。共享关系变更时,及时删除不再需要的 AP 策略和复制规则,避免权限长期残留。四种机制的选择建议
| 机制 | 适用场景 | 关键限制 |
|---|---|---|
| 存储桶策略 | 少量团队、规则简单的直接共享 | 规则集中在桶上,多了难维护 |
| ACL | 遗留系统兼容 | 粒度粗,新桶默认禁用 |
| Access Point | 多团队、多前缀、需独立策略 | 需额外管理 AP 与别名 |
| 跨账户复制 | 高频读取、低延迟、数据本地化 | 异步、需版本控制与复制角色 |
回到本节任务:团队 A 用存储桶策略或 Access Point 授予团队 B 只读 shared/ 的权限,团队 B 在角色策略中允许对应动作,双方同时满足后即可访问;若团队 B 需要长期高频使用,再叠加跨账户复制,把数据副本落到自己账户。ACL 不作为主路径。按这个组合落地,共享关系清晰、可审计,也便于后续回收。