3. IAM与跨账户访问基础
跨账户数据共享的第一道门槛不是S3桶策略,也不是Glue Catalog资源策略,而是IAM身份与授权模型。很多团队在配置跨账户访问时,习惯性地把权限直接授予对方账户的某个用户,结果要么权限过大,要么在对方人员变动后留下长期有效的“幽灵权限”。要真正实现最小权限的跨团队数据访问,必须理解IAM角色、信任策略与权限边界三者的分工,并让它们协同工作。
一、为什么跨账户访问要用角色,而不是直接授权用户
IAM用户属于某一个AWS账户,它的凭证(访问密钥、密码)由该账户管理。当A团队需要访问B团队账户中的S3数据时,如果B团队直接给A团队的某个IAM用户附加权限,会带来两个问题:一是权限依附于具体用户,人员离职或密钥轮换时难以追踪;二是B团队无法控制A团队内部谁可以使用这份权限。
正确做法是由B团队创建一个IAM角色,在角色的信任策略(Trust Policy)中声明“允许A团队账户中的特定主体来扮演我”。A团队的用户或服务通过sts:AssumeRole获取临时凭证,凭证有效期通常为15分钟到12小时。这样权限的授予对象是“角色”,而不是“某个人”,B团队始终掌握着信任关系的开关。
二、信任策略:跨账户访问的入口控制
信任策略是IAM角色的资源策略,它决定了哪些主体可以调用sts:AssumeRole。一个典型的跨账户信任策略如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "data-share-2024"
}
}
}
]
}
这里有几个关键点。第一,Principal写的是A团队的账户根ARN,但这不代表整个账户的所有用户都能扮演。实际上,A团队内部还需要通过自己的IAM策略,显式授予某个用户或角色sts:AssumeRole的权限,才能完成扮演。也就是说,跨账户访问需要双方各授权一次:B团队在信任策略中允许,A团队在身份策略中放行。
第二,Condition中的sts:ExternalId是防止“混淆代理”问题的关键。当A团队使用第三方SaaS工具访问B团队数据时,ExternalId可以确保只有持有该标识的请求才能扮演角色。对于纯内部团队协作,ExternalId不是必须的,但建议保留,作为额外的审计线索。
第三,信任策略中应尽量缩小Principal范围。如果A团队只有一个特定角色需要访问,可以直接写该角色的ARN,而不是整个账户根。这样即使A团队账户被入侵,攻击者也无法随意扮演该角色。
三、权限策略与权限边界:控制“能做什么”和“最多能做什么”
角色被扮演后,实际能执行哪些操作由权限策略(Permission Policy)决定。例如,B团队希望A团队只能读取analytics-shared桶中reports/前缀下的对象,权限策略可以写成:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::analytics-shared",
"arn:aws:s3:::analytics-shared/reports/*"
]
}
]
}
注意ListBucket作用于桶本身,GetObject作用于对象,两者资源ARN的写法不同。如果只写对象ARN而漏掉桶ARN,控制台或CLI在列举对象时会报AccessDenied,但直接读取已知对象仍然成功,这种“半通不通”的状态在排障时很常见。
权限边界(Permissions Boundary)则是一个上限。它本身不授予任何权限,只是规定“这个角色即使被附加了更多策略,实际生效的权限也不会超过边界”。在跨团队场景中,B团队可以用权限边界来限制自己团队内部创建的角色,防止某个开发者无意中给角色附加了s3:*或kms:Decrypt之外的敏感权限。权限边界与身份策略的交集才是最终生效权限。
四、最小权限的落地检查清单
在实际配置跨团队数据访问时,可以按以下顺序逐项确认,避免遗漏或过度授权:
- 信任策略的Principal是否精确到角色ARN,而不是整个账户根;如果必须用账户根,是否附加了ExternalId或SourceArn条件。
- 权限策略是否只包含必要的Action,例如只读场景下不出现
s3:PutObject、s3:DeleteObject。 - 资源ARN是否限定到前缀或具体对象,避免
arn:aws:s3:::*这类通配。 - 是否附加了权限边界,尤其是当角色由自动化流程或开发者自助创建时。
- 是否配置了CloudTrail数据事件,用于记录跨账户的
AssumeRole和S3对象访问。 - 临时凭证的会话时长是否合理,长时间运行的任务可以设置1小时,交互式分析可以缩短到15分钟。
sts:AssumeRole。如果对方没有配置,扮演会失败并返回AccessDenied。排障时先确认双方策略是否都到位。
五、验证与排障
配置完成后,可以用AWS CLI验证角色是否可以被成功扮演:
aws sts assume-role \
--role-arn arn:aws:iam::444455556666:role/DataReader \
--role-session-name test-cross-account \
--external-id data-share-2024
如果返回Credentials字段,说明信任策略和身份策略都正确。接着用返回的临时凭证尝试读取目标对象:
aws s3 cp s3://analytics-shared/reports/2024/summary.csv . \
--profile cross-account
如果AssumeRole成功但读取失败,问题通常出在权限策略的资源ARN或Action上;如果AssumeRole本身就失败,则检查信任策略的Principal、Condition以及调用方身份策略。通过CloudTrail的AssumeRole事件可以查看具体的错误码和请求参数,这是定位跨账户访问问题最直接的依据。
把IAM角色、信任策略和权限边界三者配合好,跨团队数据访问就不再是“给个账号密码”的粗放模式,而是可审计、可撤销、可收敛到最小权限的工程化实践。