IAM角色:信任策略与权限策略
好,咱们直接进入正题。IAM角色,说白了就是一个“身份容器”。它本身没有密码,也没有固定的访问密钥。谁能用这个角色?能用它干什么?这是两个完全不同的问题。对应的,就是信任策略和权限策略。
我遇到过不少同学,把这两个策略搞混。结果要么是角色建好了但没人能切换过去,要么是切换过去了但啥也干不了。今天咱们一次把它理清。
核心概念:信任策略 vs 权限策略
先看一个最直白的对比:
| 维度 | 信任策略(Trust Policy) | 权限策略(Permission Policy) |
|---|---|---|
| 解决的问题 | 谁可以用这个角色? | 这个角色能用哪些资源? |
| 附加位置 | 挂载在角色本身的“信任关系”中 | 作为角色的托管策略或内联策略 |
| 核心动作 | sts:AssumeRole |
s3:GetObject, ec2:* 等 |
| 主体(Principal) | 明确写允许哪些AWS账号、用户、服务 | 不需要指定Principal(角色本身就是主体) |
| 生效时机 | 在获取角色临时凭证之前检查 | 在临时凭证使用的时候检查 |
这个表基本把区别说清了。我习惯把信任策略比作“门禁系统”——先确认你能不能进这个门;权限策略比作“房间钥匙”——进门后你能开哪些房间的门。
信任策略:谁可以当这个角色?
信任策略是角色定义的一部分。每个角色都必须有一个信任策略(默认是拒绝所有)。它的结构里最关键的字段是 Principal 和 Action: sts:AssumeRole。
来看一个最常见的例子——允许同一个账户下的一个EC2实例来扮演这个角色:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
sts:AssumeRole 指向你这里的角色ARN。这叫双向授权。
为什么会需要双向授权?我曾经踩过这个坑。跨账户配角色时,我在A账户的信任策略里写了B账户的ID,心想这不就通了?但我忘了B账户那边还要给具体的IAM用户分配 sts:AssumeRole 的权限。结果那个用户怎么也切不过来,排查了半天。
权限策略:角色能做什么?
权限策略就是平时大家最熟悉的IAM策略。可以托管,也可以内联。但这里有个关键点:角色的权限策略中不需要写Principal。因为当用户或服务使用 sts:AssumeRole 获取到临时凭证后,这个角色的ARN就已经成为凭证的语境了。权限检查时,AWS自动把角色当作主体。
举个例子,假设我要让这个EC2角色能读取S3中某个桶的对象:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-bucket/*"
}
]
}
然后把这个策略附加给角色。完事。
嗯,这里要注意权限策略的作用范围。如果你在信任策略中允许了EC2服务,但权限策略里给的是 s3:* 允许所有桶,那这台EC2实例就真的能访问所有桶。权限边界要自己守好。
两者的协同流程
下面这张图把整个交互过程画出来了。我建议你先顺着箭头走一遍,再回来看后面的文字。
你看,流程非常清晰:
- 请求者发
sts:AssumeRole请求。 - IAM服务读取角色的信任策略,检查Principal和Action。
- 如果信任策略不允许,直接拒绝,返回错误。
- 如果允许,颁发临时安全凭证(AccessKey + SessionToken)。
- 当请求者用这个凭证去调用其他AWS服务时,IAM会基于角色的权限策略做最终授权。
ec2.amazonaws.com,但开发者直接在EC2实例里写死 aws sts assume-role 去获取另一个角色的凭证。注意,EC2服务帮你自动获取凭证,但如果你手动调STS,PassRole权限和信任策略都要重新检查。千万别混用。
实践建议:如何安全搭配?
讲了这么多,我总结几条我个人常用的原则:
- 信任策略尽量收窄。只给必要的服务或账户。比如EC2就写
ec2.amazonaws.com,Lambda就写lambda.amazonaws.com,别图省事写*。 - 权限策略用最小权限。角色能访问的资源范围越小越好。尤其当角色给EC2实例用时,实例上跑的应用如果被攻破,角色权限就是攻击者的进入门槛。
- 用条件键加固信任。比如强制要求
aws:SourceAccount或aws:SourceArn,避免混淆代理人攻击。这个后面章节会细讲。
一句话总结:信任策略决定“开不开门”,权限策略决定“进门后能去哪”。写角色配置时,这两份策略要分开思考,但最终联调时要一起验证。