3、策略模拟工具:如何使用IAM策略模拟器进行测试

说实话,策略这东西写完以后,心里总有点不踏实。我也见过不少同行——写的时候信心满满,结果部署上去要么权限过大,要么直接把人锁在外面。我自己的经验是,写策略是一回事,验证策略是另一回事。

IAM 策略模拟器,说白了就是个“沙盒”。你可以在里面模拟某个用户、角色或组的请求,看看它到底能不能通过。我每次写完新策略,都会先跑一遍模拟器,确认结果符合预期再上线。

核心观点:模拟器不产生真实效果,但能帮你提前发现策略逻辑错误。这是策略滥用检测的“第一道防线”。

模拟器到底在模拟什么?

你想想看,一个请求在 AWS 里怎么被判决的?大概三步:

  1. 收集上下文:谁(Principal)、做什么(Action)、对什么资源(Resource)、附加条件(Condition)
  2. 策略解析:把所有附加的身份策略、资源策略、SCP、会话策略拉出来,按优先级排好
  3. 最终裁决:显式拒绝 > 显式允许 > 隐式拒绝

模拟器就是把这些步骤在内存里跑一遍,然后告诉你“允许”还是“拒绝”,并且把详细的决策链列出来。嗯,这比你自己一条条读 JSON 策略快多了。

策略模拟器工作流程 主体(User/Role) 操作(Action) 资源(ARN) 条件 策略评估引擎 Identity / Resource / SCP 合并评估 允许 / 拒绝 输入:主体 + 操作 + 资源 + 条件

实战四步法

我一般按这四个步骤来跑模拟,基本上没有漏过问题。

步骤 操作内容 常用工具
1. 选择主体 指定要模拟的用户、角色或组(支持 ARN 搜索) AWS Console / CLI
2. 添加上下文 输入操作(如 s3:GetObject)、资源 ARN、VPC/IP 条件 Console 表单 / JSON 输入
3. 选择政策模拟模式 普通模式(模拟所有附加策略)或自定义策略集 勾选框 / --policy-input-list
4. 运行并分析 查看每条策略的决策链,找到隐式拒绝或意外允许 Console 结果表格 / JSON 输出

我在项目中遇到过一个经典案例:给某开发人员授予了 S3 FullAccess,但发现他无法访问某个桶。用模拟器一查,原来该桶有一条资源策略显式拒绝了这个 IAM 用户的 sub。你看,单看身份策略没问题,但加上资源策略就冲突了。模拟器把两层策略的合并结果直接亮出来,省了我半小时排错。

怎么读模拟结果?

模拟结果出来以后,你主要看这几个字段:

  • 决定:允许 / 拒绝 / 隐式拒绝。⚠️ 注意区分“显式拒绝”和“隐式拒绝”。显式拒绝说明某条策略写了 Deny,隐式拒绝只是因为没有明确允许。
  • 匹配语句:哪些策略语句参与了决策。我最喜欢点开查看匹配详情,能直接定位到具体策略 ID 和行号。
  • 原因报告:为什么拒绝?缺少什么权限?比如“缺失 s3:GetObject”或者“Condition 不满足”。我经常用这栏来教育新人——告诉他们“写的 Condition 不对,模拟器会直接标红”。

我的小技巧:模拟结果如果显示“允许”,别太高兴。记得检查一下“是否通过所有策略的允许”,有时候一条 Deny 被其他策略覆盖了,结果看上去是 Allow 但实际上 Deny 优先级更高。模拟器会把 Deny 单独列出来,你只要确认 Deny 的源不是你想拒绝的就行。

常见场景与避坑指南

我说几个实际中高频使用的场景,大部分是踩过坑后总结的。

  • 验证新策略是否过度授权:我习惯模拟一个“只读用户”身份的请求,看它能不能执行 s3:PutObject 之类的写操作。如果结果允许,说明策略比预期宽。我曾经这么抓过一次把“ListBucket”和“PutObject”写进同一条语句的乌龙。
  • 模拟跨账号访问:先选角色 ARN,然后在角色上附加信任策略的模拟。注意模拟环境不会真的调用 AssumeRole,你得手动把信任策略的 Condition 写进去。
  • 测试 Condition 条件生效:比如源 IP 限制、MFA 要求。我在 Console 里直接输入一个伪造的 IP(比如 203.0.113.1),看模拟器会不会拒绝。记住:模拟环境不会校验 IP 是否真实,它只按条件逻辑执行。
  • 批量模拟多个操作:模拟器支持一次输入多个操作。我常用这个来验证一组最小权限是否覆盖了所有必要操作。如果某个操作被拒绝且你还想要,那就得补策略了。

⚠️ 避坑指南:我踩过的大坑

  • 模拟器不模拟基于资源的策略(部分情况):例如 S3 桶策略、KMS 密钥策略需要显式指定资源。模拟器默认只评估身份策略,你必须手动勾选“包括资源策略”选项。我之前没勾,以为某个用户没有权限,结果部署后他居然能访问——原来是被资源策略允许了。
  • 模拟器不模拟 SCP 的完整效果:如果组织启用了 SCP,模拟器只会在你勾选“包括 SCP”时才评估。我建议所有跨账号模拟都手动加上 SCP。
  • 别相信“模拟通过”就万事大吉:模拟器不会模拟外部因素(比如 STS 令牌超时、权限边界未绑定)。模拟通过只是策略层正确,不代表真实环境就稳。

用 CLI 跑模拟更快

如果你跟我一样喜欢终端,那就用 iam simulate-principal-policy 命令。示例如下:

aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/DevUser \
  --action-names s3:GetObject s3:PutObject \
  --resource-arns arn:aws:s3:::my-bucket/* \
  --context-entries ContextKeyName=aws:SourceIp,ContextKeyValues=["203.0.113.0/24"] \
  --output json

输出是一堆 JSON,我一般用 jq 过滤出 EvaluationDecision 和 MatchedStatements。方便批量验证。注意 CLI 不支持图形化决策链,但可以拿到原始数据,适合接入 CI/CD 管线。

好了,模拟器就聊这么多。你大概已经发现了——模拟器并不是万能神器,但它是策略上线前的最后一道“安全检查门”。我个人建议:每次修改策略后,花5分钟跑一遍模拟,性价比极高。特别是当策略涉及 Condition、权限边界、资源策略多层叠加时,模拟器能让你在代码阶段就发现问题,而不是等故障报告。