关于 iam-recommendations-simulator
iam-recommendations-simulator 是用于批量运行 Google Cloud IAM 策略模拟的技能。它准备策略输入,调用可用的模拟方式,并将重放结果对应到各输入主体和资源。
主要功能
- 01批量模拟拟议的 IAM 策略
- 02接受内联策略或本地 JSON 文件
- 03支持 MCP、gcloud 和 API 调用路径
- 04将重放结果映射到输入模拟
- 05报告失败或受阻状态
适用场景
- 01检查针对某项资源的拟议访问权限变更
- 02在一个批次中模拟多个主体的策略
MCP 相关
如果有 IAM Policy Simulator MCP 工具,技能会优先用它执行模拟;否则按说明回退到 gcloud 和 API 调用。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ skills --skill iam-recommendations-simulator安装后在 Claude Code 中输入/iam-recommendations-simulator确认已加载。
详细介绍
IAM 策略模拟器(批量执行器)
此技能使用 Google Cloud Policy Simulator 模拟一批拟议的 IAM 策略更改。它不负责循环处理多批次或执行回退逻辑;只专注于使用给定输入执行模拟。
输入
输入必须是包含模拟数组的 JSON 对象:
{
"simulations": [
{
"id": "sim_1",
"resource": "//cloudresourcemanager.googleapis.com/projects/my-project",
"member": "user:[email protected]",
"proposed_policy": {
"bindings": [
{
"role": "roles/viewer",
"members": [
"user:[email protected]"
]
}
],
"etag": "...",
"version": 1
}
}
]
}
每个模拟对象必须包含:
id:模拟的唯一标识符(例如模拟名称)。resource:目标资源的完整名称(必须以//开头)。member:主体(例如user:、serviceAccount:、group:)。proposed_policy/proposed_policy_file:以下二者之一:表示拟议 IAM 策略的 JSON 对象(proposed_policy),或现有本地 JSON 策略文件的字符串路径(proposed_policy_file,或作为字符串路径的proposed_policy)。
流程
1. 解析输入批次
从用户请求中识别模拟批次:
- 外部文件:如果请求指定了文件路径(例如
batch.json),请使用view_file工具读取其内容。不要使用grep、find或 shell 命令搜索文件。 - 内联输入:如果模拟 JSON 数组或对象直接提供在提示文本中,请直接从上下文解析。
2. 验证 API
检查当前项目是否已启用所需 API:
policysimulator.googleapis.com
如果未启用,请勿自动启用。启用 API 可能会产生费用。必须暂停操作并明确询问用户是否确认:"The Policy Simulator API (policysimulator.googleapis.com) is not enabled on this project.
Enabling it may incur costs. Do you authorize enabling this API?"
重要:API 检查失败时立即停止:如果检查 API 状态(例如通过 gcloud services list)时因缺少凭据、权限错误或沙盒测试限制而失败,不要尝试排查凭据问题、登录身份验证或编写自定义验证脚本。立即停止执行,并明确询问用户是否授权启用 API。
只有在收到用户的明确确认后,才执行启用命令:
gcloud services enable policysimulator.googleapis.com
3. 准备策略文件
对于输入批次中的每个模拟:
- 根据
sim.id(或索引)创建一个经过清理的文件标识符{sim_id}。 - 对于拟议策略:
- 如果
sim.proposed_policy是 JSON 对象,请使用原生文件写入工具(或安全的库)将其写入磁盘,路径为/tmp/proposed_policy_SIM_ID.json。将PROPOSED_POLICY_PATH设为/tmp/proposed_policy_SIM_ID.json。 - 如果提供了
sim.proposed_policy_file(或作为字符串路径的sim.proposed_policy),请确认文件在磁盘上存在,并将PROPOSED_POLICY_PATH直接设为该文件路径。
- 如果
4. 运行模拟(回退流程)
使用拟议策略作为覆盖项运行模拟。
- 构造覆盖项:覆盖项是将资源完整名称映射到拟议策略内容的映射。
按以下顺序尝试模拟执行方式。首次成功后停止。
重要:出错时立即停止(避免因相同授权或权限原因导致冗余 API 调用失败):如果任何尝试的方法(选项 A 或选项 B)因 API 级错误(例如 PERMISSION_DENIED、UNAUTHENTICATED、NOT_FOUND 或 INVALID_ARGUMENT)或群组成员关系阻碍而失败,不要尝试任何后续选项(包括选项 C 或直接 API/curl 调用)。立即停止,不再调用任何工具,并按输出格式返回状态为 FAILED 或 BLOCKED 的结构化 JSON。
选项 A:MCP 工具(首选)
如果有可用的 MCP 工具,请使用它。MCP 工具专为在 Google 的内部环境中高效、安全地执行操作而设计,与通用 CLI 命令相比,通常能简化身份验证并提供更好的集成。
如果你的上下文中有可用的 IAM Policy Simulator MCP 工具:
- 使用模拟覆盖层参数调用该工具。
选项 B:gcloud CLI(首选备用方案)
如果 MCP 不可用,请直接执行模拟重放命令,不要使用 shell 重定向或管道:
gcloud iam simulator replay-recent-access FULL_RESOURCE_NAME PROPOSED_POLICY_PATH --format=json
直接在内存中捕获 JSON 输出(如有需要,也可以将其存储在
/tmp/raw_result_SIM_ID.json 中)。重要:异步执行:
如果 run_command 将命令作为任务发送到后台,请勿尝试读取或查看任务日志 URI(task-*.log);只需停止调用工具以结束本轮,等待系统在命令完成时自动通知你。请勿使用 grep、find 或 shell 命令来等待或搜索重放输出。
选项 C:Google Cloud API(最终备用方案)
仅当环境中确实无法使用 gcloud(例如,出现 gcloud: command not found)时,才尝试此选项。API 客户端库需要更多设置,执行开销也更大,因此只有在缺少 CLI 工具时才将其作为最后手段。如果 gcloud 可用但因 API 错误而失败,请勿使用此选项。
使用 Google Cloud Policy Simulator API 客户端库(如果无法使用客户端库,则直接调用 REST API
v1/projects/{project}/locations/global/replays)来:
- 创建重放操作。
- 轮询操作,直到完成。
- 获取重放结果。
5. 验证并处理输出
-
检查命令是否成功及输出是否有效:
- 退出状态:运行模拟命令后,检查其退出状态。非零退出状态表示失败。如果命令失败,请返回:
status:FAILEDerror:Simulation command failed for SIM_ID. Check logs for details.
- 有效 JSON:验证命令输出(或
/tmp/raw_result_SIM_ID.json)是否包含有效 JSON。如果没有,请返回:status:FAILEDerror:Invalid or missing simulation output.
- 预期结构:解析 JSON。如果缺少
replayResults等预期字段,请返回FAILED。
- 退出状态:运行模拟命令后,检查其退出状态。非零退出状态表示失败。如果命令失败,请返回:
-
检查已知阻碍:假设命令已成功执行并生成有效输出:
- 群组权限:检查目标主体是否为 Google 群组(例如
group:...),且模拟是否因权限错误而失败(或输出是否包含PERMISSION_DENIED_ON_GROUP_MEMBERSHIP)。如果是,请返回:status:BLOCKEDerror:Missing permission to view group membership
- 不受支持的资源:检查模拟是否因资源类型不受支持而失败(或输出中是否有相关警告)。如果是,请返回:
status:FAILEDerror:Simulator does not yet support all resource types
- 群组权限:检查目标主体是否为 Google 群组(例如
-
映射结果:如果输出有效且不存在阻碍,则模拟成功。将
replayResults映射回输入的模拟:- 对于每个输入模拟(
sim):- 筛选模拟器的
replayResults,其中accessTuple.principal与sim.member匹配,且accessTuple.fullResourceName与sim.resource匹配。 - 收集这些匹配结果。
- 筛选模拟器的
- 构造输出。
- 对于每个输入模拟(
6. 清理
删除第 3 步生成的所有临时策略文件(/tmp/proposed_policy_*.json)、结果文件(/tmp/raw_result_*.json)以及用于模拟的所有 Python 文件(*.py)。不要删除通过 proposed_policy_file 传入的、外部已有的策略文件,以免丢失用户提供的输入文件。
输出格式
返回一个 JSON 对象:
{
"status": "SUCCESS | FAILED | BLOCKED",
"error": "Error message if failed/blocked, otherwise null",
"results": [
{
"id": "rec_1",
"replay_results": [
// Mapped replay results for this simulation
]
}
]
}