以 AWS 官方文档为准,讲清三层问题:① 权限体系有哪些层级;② 给一个"服务账号"(workload identity)正确授权要给什么;③ Management account 与跨账户 assume role 到底是什么关系。含可交互的策略求值模拟器。
自上而下每一层都只能做「收紧」,不能放大权限 —— 这是整个 IAM 的核心设计。
explicit deny 一票否决。AWS 支持 9 类策略。按「贴在身份上」vs「贴在资源上」vs「贴在边界/组织上」分类理解,比按字母背更牢。
挂在 IAM 用户 / 组 / 角色上,规定这个身份能做什么。最常用。
AmazonS3ReadOnlyAccess挂在资源本身,规定哪个主体能动我。最常见是 S3 bucket policy。
⚠️ 跨账户访问:被访问账户的资源策略和请求方身份的 identity policy 必须同时允许。
Allow 类策略(identity / resource / session)是「授予」;boundary / SCP / RCP 是「天花板」—— 它们从不授予权限,只决定授予的上限。一条常见误区:以为挂了 SCP 就有了权限,其实没有。AWS 的官方求值顺序固定不变。下方按真实逻辑实现:默认拒绝 → 任一 Explicit Deny 即否决 → 各天花板必须放行 → 任一 Explicit Allow 即通过。试着勾选不同组合看结论。
① 默认所有请求隐式拒绝。② 检查所有策略:只要出现一条 Explicit Deny,立即否决。③ 若存在 Permissions Boundary / SCP / RCP / Session Policy 中任意一种,它们必须全部放行,否则隐式拒绝。④ 若有一条 Explicit Allow(identity 或 resource 策略),请求通过。
这里的「服务账号」= 一个非人主体(CI/CD pipeline、后端服务、定时任务)需要访问 AWS。AWS 的官方答案很明确:用 Role(角色),不是 User,并通过 federation 或交叉扮演拿临时凭证。
用 IAM Role + 实例/任务角色:
ec2.amazonaws.com / ecs-tasks.amazonaws.com / lambda.amazonaws.com用 OIDC 联邦免密钥:
token.actions.githubusercontent.com)StringEquals 限定 repo:你的org/你的repo + subAssumeRoleWithWebIdentity 换临时凭证仅当无法用角色时才退而求其次:建 IAM User + access key,只挂 programmatic access,绝不开放控制台;用 Group 或 customer-managed policy 绑权限;强制 rotation;开 key 的 last-used 监控。但官方立场是:优先 Role,User 是例外。
# 1) 角色信任策略:允许 ECS 任务扮演我
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ecs-tasks.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
# 2) 角色权限策略:只允许它读指定的桶(最小权限)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-app-data",
"arn:aws:s3:::my-app-data/*"
]
}]
}
"Action":"*" 除非临时调试);③ 写 trust policy 精确到 Principal,必要时加 ExternalId 或 Condition 防混淆代理人攻击(confused deputy)。你提到的 management account 与 assume account,对应 AWS Organizations 的真实概念:management account(管理账户) 与 member account(成员账户)+ assume role 跨账户访问。
创建 AWS Organizations 的那个账户,也叫 payer / root account。它:
多账户架构下,每个环境/团队是独立 member account。当你说「assume 到某账户」,流程是:
sts:AssumeRole(CLI: aws sts assume-role --role-arn ...)换到一组临时凭证跨账户访问成立的两个硬条件:目标账户的资源/信任策略允许你 且 你来源账户的 identity policy 允许你发起 AssumeRole。任一缺失都失败。
# 生产账户中的 Role(prod-deployer)trust policy:
# 允许「部署账户 123456789012」里的 Role 扮演我
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:role/deploy-bot" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "a-secret-only-we-know" } }
}]
}
把前面四节浓缩成可执行的检查项。