【笔记】IAM、Role 与 STS 的身份凭证链
云上权限问题最容易混乱,是因为“谁在访问”“允许做什么”“拿什么证明身份”“请求如何被验证”经常被统称为权限。AWS IAM 与 STS 把它们拆成不同对象,再在每次请求中重新组合。
本文以 AWS 为中心建立模型。其他云厂商可能有相似概念,但名称、策略求值和凭证格式并不构成一一对应的兼容协议。
1. 中心模型:主体、授权、凭证、请求认证
flowchart LR
P[Principal 主体] --> POL[Policy 授权边界]
P --> C[Credential 凭证]
C --> S[SigV4 签名请求]
S --> A[AWS 认证出调用会话]
POL --> Z[策略求值]
A --> Z
Z -->|Allow| R[执行资源操作]
Z -->|Deny| D[拒绝]
四层分别回答:
- 主体:谁在发起操作;
- 授权:这个主体在什么条件下可以做什么;
- 凭证:调用方怎样向 AWS 证明自己控制某个身份或会话;
- 请求认证:AWS 怎样验证请求未被篡改,并把它关联到主体。
Access key 不是权限策略,Role 也不是一组可以复制到机器上的静态密钥。先守住这两个边界,大部分 IAM 问题就清晰了。
2. AWS Account 与 root user
2.1 Account 是资源与权限的顶层边界
AWS account 拥有账号 ID,是 IAM 资源、账单和大量服务资源的归属边界。ARN 中的 account-id 通常表达资源或主体属于哪个账号。
账号不是一个日常登录用户。创建账号时产生的 root user 才是可登录身份。
2.2 Root user 是特殊主体
root user 使用创建账号时的邮箱等根凭证,拥有极高权限,并能完成部分只有 root 才能执行的账号级任务。
最佳实践是:
- 为 root 开启 MFA;
- 不创建 root access key;
- 除必须的账号操作外不使用 root;
- 日常管理通过联合身份或受控 IAM 身份完成。
“root account”是常见口语,但在建立权限模型时应区分 account 与 root user。
3. IAM User、Group 与 Role
3.1 IAM User 是账号内的长期身份
IAM User 代表一个人或工作负载的持久 IAM 身份,可以拥有控制台密码或长期 access key。User 的生命周期和凭证需要账号自行管理。
现代人类访问更推荐联合身份与 IAM Identity Center;IAM User 仍存在,但不应默认等同于“每个员工一个长期 AK/SK”。
3.2 Group 只聚合 User 权限
IAM Group 是 User 的集合,可以附加 permission policies,让多个 User 共享授权。Group 本身不是可登录或可 AssumeRole 的 Principal,也不拥有凭证。
3.3 Role 是可被承担的身份模板
IAM Role 定义:
- 谁可以建立这个 Role 的 session;
- session 最多拥有哪些权限;
- session 的持续时间、标签和相关条件。
Role 本身没有一组永久 AK/SK。调用方通过 STS 承担 Role 后,得到短期 session 和临时凭证。
1
2
IAM Role Assumed-role session
arn:aws:iam::123:role/App → arn:aws:sts::123:assumed-role/App/run-42
左边是配置实体,右边是一次具体会话主体。
4. Policy 不是一种单一挂载方式
4.1 Identity-based permission policy
附加到 User、Group 或 Role 的 identity-based policy 描述该身份允许或拒绝哪些 action、resource 和 condition。
例如 Role 的 policy 可以允许读取某个 S3 bucket,但这不说明谁可以承担这个 Role。
4.2 Resource-based policy
某些服务资源可以直接声明允许哪些 Principal 访问,例如 S3 bucket policy、KMS key policy。它从资源侧参与求值。
并非所有服务都支持同样的 resource policy,也不能把 S3 的策略经验无差别套到其他服务。
4.3 Permissions boundary、SCP 与 session policy
真实有效权限还可能被多层上限约束:
- permissions boundary 限制 identity-based policy 最多能授予什么;
- AWS Organizations SCP 限制组织或账号内身份可获得的最大权限;
- STS session policy 进一步缩小一次会话的权限;
- service-specific policy 可能有自己的求值规则。
它们通常是权限上限,不会凭空补出基础 policy 没有授予的 Allow。
4.4 显式 Deny 优先
IAM 求值不是简单把所有 Allow 相加。一般模型是:先确认是否存在适用 Allow,再检查任何相关层是否有显式 Deny;显式 Deny 会覆盖 Allow。
具体请求还要结合主体类型、同账号或跨账号、资源策略、boundary 和 SCP。排障时必须用实际 request context 分析,不能只盯着某一张 policy。
5. Role 为什么有两类策略
5.1 Trust policy 回答“谁可以进来”
Role 的 trust policy 是附在 Role 上的 resource-based policy,核心 action 通常是:
1
2
3
4
5
6
7
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/Caller"
},
"Action": "sts:AssumeRole"
}
它声明哪些 Principal 在什么条件下可以尝试建立 Role session。
5.2 Permission policy 回答“进来后能做什么”
附在 Role 上的 identity-based policies 决定 Role session 对业务资源的基础权限,例如 s3:GetObject 或 dynamodb:PutItem。
5.3 两类 policy 不能互相替代
只有 permission policy:Role 有能力定义,但没人被信任来承担它。
只有 trust policy:调用方可能能建立 session,但 session 没有相应业务操作的 Allow。
1
2
Trust policy = 建立身份会话的入口条件
Permission policy = 会话建立后的业务权限上限
6. AssumeRole 的双边授权
6.1 调用方先要能调用 STS
调用方使用已有凭证签名 sts:AssumeRole 请求,并指定目标 Role ARN 与 session name。
跨账号典型场景通常需要:
- 调用方一侧的 identity policy 允许对目标 Role 执行
sts:AssumeRole; - 目标 Role 的 trust policy 信任调用方 Principal。
同账号下某些 trust policy 直接授权主体时,identity policy 是否还需额外 Allow 会受 Principal 写法和 IAM 求值规则影响。不要把“永远两张 Allow”当成无条件公式,但跨账号排障用双边模型最稳妥。
6.2 STS 创建的是 session,不是修改调用方身份
授权通过后,STS 返回:
AccessKeyId;SecretAccessKey;SessionToken;Expiration;AssumedRoleUser标识。
原调用方身份仍然存在。临时凭证代表一个新的 assumed-role session,后续请求的 Principal 也切换到该 session。
6.3 Session name 是审计维度
session name 会出现在 assumed-role ARN 和 CloudTrail 等记录里:
1
arn:aws:sts::123456789012:assumed-role/AppRole/deploy-42
它帮助区分多次承担同一 Role 的会话,但不是秘密,也不是授权凭证。
6.4 Session policy 只能收窄
调用 AssumeRole 时可以传入 inline 或 managed session policies。最终 session 权限是 Role identity policies 与 session policies 等约束的交集;session policy 不能授予 Role 原本没有的权限。
此外还可能受 permissions boundary、SCP、资源策略和显式 Deny 限制。
7. Temporary credentials 的三个部件
7.1 Access key ID 是查找标识
Access key ID 让 AWS 定位对应的长期身份或临时 session。它会出现在 SigV4 Credential 字段中,但它不是主体 ARN,也不是秘密本身。
7.2 Secret access key 用于计算签名
Secret access key 参与 HMAC 派生和请求签名。客户端与 AWS 都不通过网络直接传输 secret;服务端根据 access key ID 找到对应 secret,再计算期望签名。
7.3 Session token 证明临时会话上下文
临时凭证必须同时携带 session token,通常放在 X-Amz-Security-Token。只拿临时 AK/SK 而漏掉 token,请求仍会失败。
token 不替代签名。三者共同工作:
1
AccessKeyId + SecretAccessKey + SessionToken + Expiration
临时凭证到期后不能继续使用,需要重新获取,而不是延长原凭证本身。
8. 计算凭证如何交给工作负载
8.1 不要把长期密钥烘焙进机器
EC2、Lambda、ECS 和 EKS 等环境都有把 Role session 临时凭证交给工作负载的机制。共同目标是:应用获得短期凭证,而不是在镜像、磁盘或环境配置中长期保存 IAM User secret。
8.2 计算资源不是 IAM Principal 本体
以 EC2 为例,实例本身不是“拥有 permission policy 的 IAM User”。instance profile 把 IAM Role 关联给 EC2,平台再提供该 Role 的临时凭证。
后续 AWS API 看到的是 assumed-role session,而不是一个抽象的“EC2 主体”。
8.3 Credential provider chain 负责获取,不负责授权
SDK 可以从环境变量、shared config、web identity、容器 endpoint 或 instance metadata 等来源寻找凭证。provider chain 解决“去哪里拿 credential”,最终权限仍由 credential 对应的主体和 policy 决定。
9. SigV4 如何把请求绑定到凭证
9.1 客户端先构造 canonical request
SigV4 将 HTTP method、规范化 URI、query、指定 headers 和 payload hash 组织成 canonical request。任何已签名部分被修改,服务端重算结果都会不同。
9.2 再构造 string to sign
string to sign 包含算法、时间、credential scope 和 canonical request hash。credential scope 通常限定:
1
YYYYMMDD/region/service/aws4_request
它让派生签名密钥绑定到日期、Region 和服务,而不是直接用长期 secret 对所有请求做同一种签名。
9.3 Authorization header 不携带 secret
典型结构是:
1
2
3
4
Authorization: AWS4-HMAC-SHA256
Credential=<AccessKeyId>/<scope>,
SignedHeaders=<headers>,
Signature=<hex>
临时凭证还要传 session token。服务端按 access key ID 找到凭证上下文,重建 canonical request 与 signing key,验证签名、时间窗口、token 和权限。
9.4 认证成功不等于授权成功
签名正确只证明:请求由掌握有效凭证的一方发出,且签名覆盖的内容未被篡改。AWS 仍要对 action、resource、condition 和所有 policy 层进行授权求值。
1
SigV4 authentication passed ≠ IAM authorization allowed
10. ARN 的真正作用
ARN 是 AWS 资源名称,用于在策略、API 和日志中标识资源或主体:
1
arn:partition:service:region:account-id:resource
不同服务的 resource 部分格式不同,部分字段可以为空。例如 IAM Role ARN 与 STS assumed-role ARN 的 service 和 resource 结构就不同。
ARN 不等于 credential:
- ARN 标识“是谁或是什么”;
- access key ID 帮助定位凭证记录;
- secret 用于证明控制权;
- session token 绑定临时会话。
11. 一次跨账号访问的完整链路
sequenceDiagram
participant C as Account A Caller
participant STS as AWS STS
participant R as Account B Role
participant S3 as Account B S3
C->>STS: 用现有凭证签名 AssumeRole
STS->>R: 检查 trust policy 与条件
STS->>STS: 检查调用方权限和其他边界
STS-->>C: 临时 AK/SK/token + expiration
C->>S3: 用临时凭证签名 GetObject
S3->>S3: 认证 assumed-role session
S3->>S3: 求值 Role、session、SCP、resource policy
S3-->>C: Allow 或 Deny
这里发生了两次不同授权:第一次授权能否建立 Role session,第二次授权该 session 能否访问业务资源。
12. 常见误区
12.1 “AK 上挂了策略”
策略挂在 User、Group、Role 或资源等实体上。AK 只是某个身份或 session 的凭证组成,不是 policy attachment target。
12.2 “Role 就是一组临时 AK/SK”
Role 是 IAM 配置实体;STS 根据一次成功的 AssumeRole 创建 session,才产生临时凭证。
12.3 “Trust policy 已经允许 S3”
Trust policy 的核心职责是允许建立 Role session。业务资源权限由 Role permission policy 等层决定。
12.4 “签名通过就一定有权限”
签名属于认证。认证后还要进行策略求值;显式 Deny、SCP、boundary、session policy 或资源策略都可能导致拒绝。
12.5 “跨云概念完全等价”
RAM、IAM、STS、service account 等名称可能相似,但主体模型、token 格式和策略求值存在差异。对照表只能帮助迁移认知,不能代替目标云官方文档。
13. 排障顺序
面对 AccessDenied,按链路排查比盲目加 Allow 更安全:
- 当前 SDK 实际使用哪组 credential;
sts get-caller-identity看到哪个 Principal;- 临时 credential 是否过期、是否包含 session token;
- 失败发生在 AssumeRole,还是承担 Role 后的业务 API;
- trust policy 与调用方权限是否满足;
- Role permission、session policy、boundary、SCP 和资源策略如何求值;
- Region、service、时间和 signed headers 是否导致 SigV4 认证失败。
不要用扩大到 Action: "*"、Resource: "*" 作为第一反应。那会掩盖主体或信任链错误,并扩大事故面。
14. 复习索引
- Principal 是身份,policy 是授权,credential 是证明材料,SigV4 是请求认证;
- User 是长期身份,Group 聚合 User 权限,Role 是可被承担的身份模板;
- Role trust policy 决定谁能建立 session,permission policy 决定 session 的基础业务权限;
- AssumeRole 返回新的 assumed-role session 和临时 AK/SK/token,不会改写原主体;
- session policy 只能收窄 Role 权限,显式 Deny 和其他上限仍然有效;
- SigV4 验证凭证控制权和请求完整性,认证成功后仍需 IAM 授权。
15. 核验入口
- AWS IAM User Guide:identities、policies、policy evaluation logic;
- AWS STS
AssumeRoleAPI:信任关系、session policies、临时凭证和 session ARN; - AWS Signature Version 4 文档:canonical request、credential scope、signing key 与 Authorization header;
- 各计算服务的 credential provider 文档:EC2 instance profile、ECS task role、EKS IRSA/Pod Identity 等具体交付方式。