模拟政策更改

本页面介绍了如何使用政策模拟器模拟 Identity and Access Management (IAM) 政策更改。此外,本页面还介绍了如何解读模拟结果以及如何应用模拟的政策(如果您选择这样做)。

准备工作

获取权限

在模拟政策更改之前,您需要确保具有适当的权限。某些权限需要运行模拟;另一些权限则不需要,但有助于您从模拟中获得最完整的结果。

如需详细了解 IAM 角色,请参阅 了解角色

必需的目标资源权限

模拟的目标资源是要模拟其政策的资源。

您需要对目标资源拥有 Simulator Admin 角色 (roles/policysimulator.admin)、Security Reviewer 角色 (roles/iam.securityReviewer) 或具有以下权限的其他角色:

  • policysimulator.replays.run
  • cloudassets.assets.searchAllResources
  • service.resource.getIamPolicy,其中 resource 是目标资源的资源类型,service 是拥有该资源的 Google Cloud 服务的名称。

必需的主机资源权限

模拟的托管资源是创建并运行模拟的项目、文件夹或组织。主机资源不需要与目标资源以任何方式相关。

设置主机资源的方式取决于您使用的平台。

控制台

主机资源是资源选择器中显示的项目、文件夹或组织。

如需更改主机资源,请在资源选择器中选择其他项目、文件夹或组织。

gcloud

主机资源是当前配额项目。如需设置配额项目,请使用 gcloud auth application-default set-quota-project 命令。

REST

每次发送请求时,您手动指定主机资源。如需了解详情,请参阅本页面上的模拟政策更改

您需要具有主机资源的 Simulator Admin 角色 (roles/policysimulator.admin) 或其他包含以下权限的角色:

  • policysimulator.replays.create
  • policysimulator.replays.get
  • policysimulator.replayResults.list

为了获得最佳的模拟结果,我们建议您拥有特定的 IAM 和 Google Workspace 权限。如果您没有以上部分或全部权限,则仍可以运行模拟。但是,运行没有这些权限的模拟可能会导致未知的访问权限更改数量增加,因为您可能无法检索可能影响模拟结果的信息。

我们建议您在运行模拟时拥有 Organization Security Reviewer 角色 (roles/iam.securityReviewer)。或者,如果您已拥有 Security Admin 角色 (roles/iam.securityAdmin),则无需授予任何其他角色。

这些角色可为您提供以下权限,帮助您从模拟中获得最完整的结果:

  • 定义了自定义角色的任何相关项目、文件夹或组织的 iam.roles.getiam.roles.list 权限。如果某个项目、文件夹或组织是您要模拟其政策的资源的祖先或子级,则该项目、文件夹或组织是相关的。
  • service.resource.getIamPolicy,其中 resource 是可以拥有 IAM 政策的资源类型的名称,service 是拥有该资源的 Google Cloud 服务的名称。

    在运行模拟时,我们建议您对每个符合以下条件的资源拥有此权限:

    • 政策模拟器 支持资源
    • 该资源的 IAM 政策可能会影响用户的访问权限。如果存在以下任一情况,也是如此:

      • 该资源是其模拟政策的资源的后代,它显示在相关访问日志中。
      • 资源是您要模拟其政策的资源的祖先实体。

    例如,假设您要模拟项目的政策。如果访问日志包含对项目中 Cloud Storage 存储分区的访问尝试,您需要该存储分区的 storage.buckets.getIamPolicy 权限。如果项目具有具有 IAM 政策的父文件夹,则您还需要该文件夹的 resourcemanager.folders.getIamPolicy 权限。

我们建议您有权检索原始政策和建议政策中每个 Google 群组的群组成员资格信息。

Google Workspace 超级用户和群组管理员通常有权查看群组成员资格。如果您不是超级用户或群组管理员,请让 Google Workspace 管理员执行以下操作:创建自定义 Google Workspace 管理员角色,其中包含groups.read权限(位于Admin API 权限),然后将其授予您。这样,您就可以查看网域中所有群组的成员资格,并更有效地模拟政策更改。

模拟政策更改

按照以下步骤模拟政策更改。

控制台

以下示例演示了如何模拟项目的政策更改。不过,您可以为具有 IAM 政策的任何资源模拟政策更改。

修改主帐号的权限,然后点击模拟,而不是点击保存

  1. 在 Cloud Console 中,转到 IAM 页面。

    转到 IAM 页面

  2. 通过修改现有主帐号的权限来创建建议的政策更改:

    1. 找到要修改其访问权限的主帐号,然后点击右侧的修改 按钮。
    2. 通过添加新角色或者撤消或更改现有角色来修改主帐号的访问权限。
  3. 要模拟更改建议,请点击模拟

  4. 几分钟后,Cloud Console 会将模拟政策的结果显示为访问权限更改列表。如需了解详情,请参阅了解政策模拟器结果

    如果现有政策与模拟政策之间的访问权限未发生任何变化,则 Cloud Console 不会显示任何访问权限更改。

gcloud

如需模拟政策更改,请遵循读取-修改-写入模式,但要模拟政策而不是写入政策。

  1. 通过运行以下命令读取当前政策:

    gcloud resource-type get-iam-policy resource-id --format=format > filepath
    

    替换以下值:

    • resource-type:要为其模拟政策的资源类型。例如 projects
    • resource-id:您要模拟其政策的资源的 ID。例如 my-project
    • format:值 JSONYAML
    • filepath:指向政策的新输出文件的路径。

    例如,以下命令以 JSON 格式获取项目 my-project 的政策,并将其保存到用户的主目录:

    gcloud projects get-iam-policy my-project --format=json > ~/policy.json
    
  2. 修改 get-iam-policy 命令返回的 JSON 或 YAML 政策,以反映您要模拟的政策更改。

    您可以对政策绑定进行多种更改。例如,您可以在角色绑定中添加或移除主帐号,或者从政策中移除角色绑定。

  3. 运行以下命令来模拟政策更改:

    gcloud iam simulator replay-recent-access \
        full-resource-name \
        filepath \
        --format=format
    

    替换以下值:

    • full-resource-name:您要模拟其政策的资源的完整资源名称。

      完整资源名称是一个 URI,由服务名称和资源路径组成。例如,如果您要模拟项目的政策,请使用 //cloudresourcemanager.googleapis.com/projects/project- id,其中 project-id 是您要模拟的政策的项目的 ID。

      如需完整的资源名称格式列表,请参阅完整资源名称

    • filepath:包含要模拟的修改后的政策的文件的路径。例如 ~/proposed_policy.json

    • format:响应的格式。例如 jsonyaml

    几分钟后,该命令会输出重放结果列表,说明主帐号的访问权限在应用建议的政策后会如何变化。这些结果还列出了模拟期间出现的任何错误,包括由于不受支持的资源类型而导致的任何错误。

    请参阅此页面上的了解政策模拟器结果,了解如何读取结果。如需了解如何保存模拟结果而不是输出结果,请参阅保存模拟结果

    以下是涉及用户 my-user@example.com 的政策模拟的示例响应。在这种情况下,如果应用建议的更改,则 my-user@example.com 可能不再具有项目 my-projectresourcemanager.projects.listresourcemanager.projects.get 权限,并且当然,不再具有项目 my-projectresourcemanager.projects.update 权限:

    [
      {
        "accessTuple": {
          "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
          "permission": "resourcemanager.projects.list",
          "principal": "my-user@example.com"
        },
        "diff": {
          "accessDiff": {
            "accessChange": "ACCESS_MAYBE_REVOKED",
            "baseline": {
              "accessState": "GRANTED"
            },
            "simulated": {
              "accessState": "UNKNOWN_INFO_DENIED",
              "errors": [
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                      "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                      "resourceType": "cloudresourcemanager.googleapis.com/projects"
                    }
                  ],
                  "message": "Missing permission to get relevant IAM policies."
                }
              ],
              "policies": [
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "policy": {}
                }
              ]
            }
          }
        },
        "lastSeenDate": {
          "day": 12,
          "month": 1,
          "year": 2021
        }
      },
      {
        "accessTuple": {
          "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
          "permission": "resourcemanager.projects.get",
          "principal": "my-user@example.com"
        },
        "diff": {
          "accessDiff": {
            "accessChange": "ACCESS_MAYBE_REVOKED",
            "baseline": {
              "accessState": "GRANTED"
            },
            "simulated": {
              "accessState": "UNKNOWN_INFO_DENIED",
              "errors": [
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to view group membership.",
                      "resourceName": "group:everyone@example.com",
                      "resourceType": "Google group"
                    }
                  ],
                  "message": "Missing permission to view group membership."
                },
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                      "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                      "resourceType": "cloudresourcemanager.googleapis.com/projects"
                    }
                  ],
                  "message": "Missing permission to get relevant IAM policies."
                }
              ],
              "policies": [
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "bindingExplanations": [
                    {
                      "access": "UNKNOWN_INFO_DENIED",
                      "memberships": {
                        "group:everyone@example.com": {
                          "membership": "MEMBERSHIP_UNKNOWN_INFO_DENIED"
                        }
                      },
                      "role": "roles/owner"
                    }
                  ],
                  "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                  "policy": {
                    "bindings": [
                      {
                        "members": [
                          "group:everyone@example.com"
                        ],
                        "role": "roles/owner"
                      }
                    ],
                    "etag": "BwWgJSIInYA=",
                    "version": 3
                  }
                },
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "policy": {}
                }
              ]
            }
          }
        },
        "lastSeenDate": {
          "day": 10,
          "month": 1,
          "year": 2021
        }
      },
      {
        "accessTuple": {
          "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
          "permission": "resourcemanager.projects.update",
          "principal": "my-user@example.com"
        },
        "diff": {
          "accessDiff": {
            "accessChange": "ACCESS_REVOKED",
            "baseline": {
              "accessState": "GRANTED"
            },
            "simulated": {
              "accessState": "NOT_GRANTED"
            }
          }
        },
        "lastSeenDate": {
          "day": 15,
          "month": 1,
          "year": 2021
        }
      },
      {
        "accessTuple": {},
        "error": {
          "code": 12,
          "details": [
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.create"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.setIamPolicy"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.delete"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.update"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "pubsub.topics.publish"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.list"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.getIamPolicy"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            },
            {
              "@type": "type.googleapis.com/google.rpc.ErrorInfo",
              "domain": "policysimulator.googleapis.com",
              "metadata": {
                "permission": "storage.objects.get"
              },
              "reason": "UNSUPPORTED_RESOURCE"
            }
          ],
          "message": "Simulator does not yet support all resource types for 8 removed permissions."
        }
      }
    ]
    

    如果现有政策与模拟政策之间的访问权限没有变化,则该命令会输出 No access changes found in the replay

REST

如需模拟政策更改,请遵循读取-修改-写入模式,但应创建并运行模拟,而不是编写政策。

  1. 读取资源的 IAM 政策:

    Resource Manager API 的 projects.getIamPolicy 方法可获取项目的 IAM 政策。

    在使用任何请求数据之前,请先进行以下替换:

    • PROJECT_ID:您的 Google Cloud 项目 ID。 项目 ID 是字母数字字符串,例如 my-project
    • POLICY_VERSION:要返回的政策版本。请求应指定最新的政策版本,即政策版本 3。如需了解详情,请参阅在获取政策时指定政策版本

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:getIamPolicy

    请求 JSON 正文:

    {
      "options": {
        "requestedPolicyVersion": POLICY_VERSION
      }
    }
    

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/owner",
          "members": [
            "user:project-owner@example.com"
          ]
        },
        {
          "role": "roles/iam.securityReviewer",
          "members": [
            "user:fatima@example.com"
          ]
        }
      ]
    }
    

  2. 修改返回的政策,以反映您要模拟的更改。

    您可以对政策绑定进行多种更改。例如,您可以在角色绑定中添加或移除主帐号,或者从政策中移除角色绑定。

  3. 使用修改后的政策创建模拟或重放

    政策模拟器 API 的 replays.create 方法可为项目、文件夹或组织创建重放。

    在使用任何请求数据之前,请先进行以下替换:

    • host-resource-type:将托管 Replay 的资源类型。此值必须为 projectsfoldersorganizations
    • host-resource-id:主机资源的 ID,例如 my-project
    • target-full-resource-name:您要模拟其政策的资源的完整资源名称。此资源可以是接受 IAM 政策的任何资源,而无需以任何方式与主机资源相关。

      完整资源名称是一个 URI,由服务名称和资源路径组成。例如,如果您要模拟项目的政策,请使用 //cloudresourcemanager.googleapis.com/projects/project- id,其中 project-id 是您要模拟的政策的项目的 ID。

      如需资源名称格式的完整列表,请参阅完整资源名称

    • policy:您要模拟的政策。如需查看政策示例,请参阅政策参考文档

      要模拟多项政策,请在请求正文中添加多个 "object-full-resource-name" : policy 对。

    HTTP 方法和网址:

    POST https://policysimulator.googleapis.com/v1/host-resource-type/host-resource-id/locations/global/replays

    请求 JSON 正文:

    {
      "config": {
        "policyOverlay": {
          "target-full-resource-name" : policy
        }
      }
    }
    

    如需发送您的请求,请展开以下选项之一:

    响应包含表示重放的操作名称:

    {
      "name": "operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8",
      "metadata": {
        "type_url": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata"
      }
    }
    

  4. 轮询 operations.get 方法,直到重放完成。

    如要轮询操作,我们建议您重复调用 operations.get 方法,直到响应包含字段 "done": truename 字段以及已完成的重放的名称。使用截断指数退避算法在每个请求之间引入延迟。

    政策模拟器 API 的 operations.get 方法可获取重放状态。

    在使用任何请求数据之前,请先进行以下替换:

    • operation-name:重放操作的名称,包括 operations 前缀。从 replays.create 响应的 name 字段中复制此值。例如:operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8

    HTTP 方法和网址:

    GET https://policysimulator.googleapis.com/v1/operation-name

    如需发送您的请求,请展开以下选项之一:

    正在进行的操作会返回如下所示的响应:

    {
      "name": "operations/42083b6b-3788-41b9-ae39-e97d7615a22d",
      "metadata": {
        "@type": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata",
        "startTime": "2021-01-15T05:34:14.732Z"
      }
    }
    

    已完成的操作会返回如下所示的响应:

    {
      "name": "operations/89ab4892-9605-4c84-aedb-4fce4fc5195b",
      "metadata": {
        "@type": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata",
        "startTime": "2021-01-15T05:40:15.922Z"
      },
      "done": true,
      "response": {
        "@type": "type.googleapis.com/google.cloud.policysimulator.v1.Replay",
        "replay": {
          "name": "projects/my-project/locations/global/replays/89ab4892-9605-4c84-aedb-4fce4fc5195b",
          "state": SUCCEEDED,
          "config": {},
          "resultsSummary": {
            "logCount": 1319,
            "unchangedCount": 1169,
            "differenceCount": 149,
            "errorCount": 1,
            "oldestDate": {
              "year": 2020,
              "month": 10,
              "day": 15
            },
            "newestDate": {
              "year": 2021,
              "month": 1,
              "day": 12
            }
          }
        }
      }
    }
    

  5. 获取 Replay 的结果。

    政策模拟器 API 的 replays.results.list 方法可获取重放的结果。

    在使用任何请求数据之前,请先进行以下替换:

    • replay-name:要为其检索结果的重放的名称。从 operations.get 响应的 response.replay.name 字段中复制此值。包括任何资源类型和位置前缀。例如:"projects/my-project/locations/global/replays/89ab4892-9605-4c84-aedb-4fce4fc5195b"
    • page-size:可选。要从此请求返回的最大结果数。如果未指定,则服务器将决定要返回的结果数。如果结果数大于页面大小,则响应中会包含分页令牌,您可以使用该令牌检索下一页结果。
    • page-token:可选。此方法之前的响应中返回的分页令牌。如果已指定,则结果列表将从上一个请求结束的位置开始。

    HTTP 方法和网址:

    GET https://policysimulator.googleapis.com/v1/replay-name/results?pageSize=page-size&pageToken=page-token

    如需发送您的请求,请展开以下选项之一:

    响应包含一系列结果,说明了如果应用建议的政策,主帐号的访问权限将如何变化。这些结果还列出了在模拟过程中发生的所有错误,最值得注意的是,由于不受支持的资源类型而导致的错误

    请参阅本页面上的了解政策模拟器结果,了解如何读取结果。

    以下是涉及用户 my-user@example.com 的政策模拟的示例响应。在这种情况下,如果应用了建议的更改,my-user@example.com 可能不再具有项目 my-projectresourcemanager.projects.listresourcemanager.projects.get 权限,并且当然不再具有项目 my-projectresourcemanager.projects.update 权限:

    {
      "replayResults": [
        {
          "accessTuple": {
            "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
            "permission": "resourcemanager.projects.list",
            "principal": "my-user@example.com"
          },
          "lastSeenDate": {
            "day": 27,
            "month": 3,
            "year": 2020
          },
          "diff": {
            "accessDiff": {
              "accessChange": "ACCESS_MAYBE_REVOKED",
              "baseline": {
                "accessState": "GRANTED"
              },
              "simulated": {
                "accessState": "UNKNOWN_INFO_DENIED",
                "errors": [
                  {
                    "code": 7,
                    "message": "Missing permission to get relevant IAM policies.",
                    "details": [
                      {
                        "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                        "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                        "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                        "resourceType": "cloudresourcemanager.googleapis.com/projects"
                      }
                    ]
                  }
                ],
                "policies": [
                  {
                    "access": "UNKNOWN_INFO_DENIED",
                    "policy": {}
                  }
                ]
              }
            }
          }
        },
        {
          "accessTuple": {
            "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
            "permission": "resourcemanager.projects.get",
            "principal": "my-user@example.com"
          },
          "lastSeenDate": {
            "day": 27,
            "month": 3,
            "year": 2020
          },
          "diff": {
            "accessDiff": {
              "accessChange": "ACCESS_MAYBE_REVOKED",
              "baseline": {
                "accessState": "GRANTED"
              },
              "simulated": {
                "accessState": "UNKNOWN_INFO_DENIED",
                "errors": [
                  {
                    "code": 7,
                    "message": "Missing permission to view group membership.",
                    "details": [
                      {
                        "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                        "description": "Missing permission to view group membership.",
                        "resourceName": "group:everyone@example.com",
                        "resourceType": "Google group"
                      }
                    ]
                  },
                  {
                    "code": 7,
                    "message": "Missing permission to get relevant IAM policies.",
                    "details": [
                      {
                        "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                        "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                        "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                        "resourceType": "cloudresourcemanager.googleapis.com/projects"
                      }
                    ]
                  }
                ],
                "policies": [
                  {
                    "access": "UNKNOWN_INFO_DENIED",
                    "bindingExplanations": [
                      {
                        "access": "UNKNOWN_INFO_DENIED",
                        "memberships": {
                          "group:everyone@example.com": {
                            "membership": "MEMBERSHIP_UNKNOWN_INFO_DENIED"
                          }
                        },
                        "role": "roles/owner"
                      }
                    ],
                    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                    "policy": {
                      "bindings": [
                        {
                          "members": [
                            "group:everyone@example.com"
                          ],
                          "role": "roles/owner"
                        }
                      ],
                      "etag": "BwWgJSIInYA=",
                      "version": 3
                    }
                  },
                  {
                    "access": "UNKNOWN_INFO_DENIED",
                    "policy": {}
                  }
                ]
              }
            }
          }
        },
        {
          "accessTuple": {
            "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
            "permission": "resourcemanager.projects.update",
            "principal": "my-user@example.com"
          },
          "lastSeenDate": {
            "day": 27,
            "month": 3,
            "year": 2020
          },
          "diff": {
            "accessDiff": {
              "accessChange": "ACCESS_REVOKED",
              "baseline": {
                "accessState": "GRANTED"
              },
              "simulated": {
                "accessState": "NOT_GRANTED"
              }
            }
          }
        },
        {
          "accessTuple": {},
          "error": {
            "code": 12,
            "message": "Simulator does not yet support all resource types for 8 removed permissions.",
            "details": [
              {
                "@type": "type.googleapis.com/google.rpc.Status",
                "code": 12,
                "message": "Simulator does not yet support all resource types for 8 removed permissions.",
                "details": [
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.create"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.setIamPolicy"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.delete"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.update"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "pubsub.topics.publish"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.list"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.getIamPolicy"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  },
                  {
                    "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                    "domain": "policysimulator.googleapis.com",
                    "metadata": {
                      "permission": "storage.objects.get"
                    },
                    "reason": "UNSUPPORTED_RESOURCE"
                  }
                ]
              }
            ]
          }
        }
      ],
      "nextPageToken": "AWukk3zjv80La+chWx6WNt7X8czGPLtP792gRpkNVEV/URZ/VdWzxmuJKr"
    }
    

    如果现有政策与模拟政策之间的访问权限没有变化,则请求将返回空列表 ({})。

了解政策模拟器结果

政策模拟器将建议的更改变更列表作为访问权限更改列表报告。访问权限更改表示过去 90 天内的访问尝试次数,该结果会导致更改政策低于当前政策。

政策模拟器还列出了模拟期间发生的所有错误,从而帮助您识别模拟中的潜在差距。

这些更改和错误的呈现方式取决于您使用的平台。

控制台

政策模拟器结果页面会在几个不同的部分中显示模拟结果:

  • 政策概览:此部分列出了主帐号在资源上具有的原始角色,以及他们在建议的政策中具有的角色。原始角色列在现有政策下,建议的角色列在推荐的政策下。

  • 访问权限变更摘要:此部分会显示过去 90 天内访问尝试的次数,如果所建议的政策落实到位,这些访问方式会有所不同。此摘要包括任何潜在或未知的访问更改,以及模拟期间发生的任何错误。

  • 过去 90 天内的访问更改:本部分列出过去 90 天内发生的、原本会采用不同访问政策的情况。每个条目(或访问权限更改)包括访问权限更改的类型,以及访问尝试中涉及的资源、主帐号和权限。

    访问权限有以下几种类型:

    访问权限变更 详细信息
    访问权限已被撤消 该主帐号根据当前政策拥有访问权限,但在实施建议更改之后将会失去此访问权限。
    访问权限可能已被撤消

    出现此结果的原因如下:

    • 该主帐号在当前政策下拥有访问权限,但其在建议政策下的访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会失去此访问权限。
    已获得访问权限 该主帐号根据当前政策无访问权限,但在实施建议更改之后将会获得此访问权限。
    可能已获得访问权限

    出现此结果的原因如下:

    • 该主帐号根据当前政策无访问权限,但在实施建议更改之后,其访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会获得此访问权限。
    访问权限未知 在当前政策和建议政策下,该主帐号的成员访问权限均为未知,并且建议的更改可能会影响该主帐号的访问权限。
    错误 模拟过程中发生错误。

    如需查看有关访问权限更改的其他详细信息,请点击访问权限更改。此操作会打开访问权限更改详细信息面板,其中显示有关访问权限更改的其他信息,包括主帐号的现有访问权限、主帐号的建议访问权限以及有关访问权限更改结果的其他详细信息。

gcloud

使用 replay-recent-access 命令时,gcloud 工具的响应包含 replayResults 列表。

每个重放结果都会描述一次访问尝试,如果尝试采用的政策已存在,则访问结果会有所不同。例如,以下重放结果表明,my-user@example.com 过去曾使用 resourcemanager.projects.update 权限在项目 my-project 中执行操作。但是,如果建议的政策落实到位,则会被拒绝。

{
  "accessTuple": {
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "resourcemanager.projects.update",
    "principal": "my-user@example.com"
  },
  "lastSeenDate": {
    "day": 15,
    "month": 1,
    "year": 2021
  },
  "diff": {
    "accessDiff": {
      "baseline": {
        "accessState": "GRANTED"
      },
      "simulated": {
        "accessState": "NOT_GRANTED"
      },
      "accessChange": "ACCESS_REVOKED"
    }
  }
}

每个重放结果包含以下字段:

  • accessTuple:与结果相关的访问尝试。此字段包括访问尝试所涉及的资源、权限和主帐号。

  • lastSeenDate:上次访问的日期。

  • diff.accessDiff error:如果访问尝试重放成功,则结果将包含diff.accessDiff字段,用于报告当前政策与建议的政策下的访问尝试结果之间的差异。如果重放尝试不成功,则重放结果将包含 error 字段以及错误说明。如需详细了解模拟错误,请参阅本页面上的错误

每个访问差异都具有以下组件:

  • baseline:使用当前政策时的访问结果。系统将其报告为以下值之一:GRANTEDNOT_GRANTEDUNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED。如果结果为 UNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED,则响应还会列出与未知信息关联的所有错误,以及与该错误关联的政策。如需详细了解 UNKNOWN 值,请参阅本页面上的未知结果
  • simulated:使用建议的政策时的访问结果。系统将其报告为以下值之一:GRANTEDNOT_GRANTEDUNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED。如果结果为 UNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED,则响应还会列出与未知信息关联的所有错误,以及与该错误关联的政策。如需详细了解 UNKNOWN 值,请参阅本页面上的未知结果
  • accessChange:基准访问状态与模拟访问状态间的变化。如需查看可能的值的列表,请参阅下表:

    访问权限变更 详细信息
    ACCESS_REVOKED 该主帐号根据当前政策拥有访问权限,但在实施建议更改之后将会失去此访问权限。
    ACCESS_MAYBE_REVOKED

    出现此结果的原因如下:

    • 该主帐号在当前政策下拥有访问权限,但其在建议政策下的访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会失去此访问权限。
    ACCESS_GAINED 该主帐号根据当前政策无访问权限,但在实施建议更改之后将会获得此访问权限。
    ACCESS_MAYBE_GAINED

    出现此结果的原因如下:

    • 该主帐号根据当前政策无访问权限,但在实施建议更改之后,其访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会获得此访问权限。
    UNKNOWN_CHANGE 在当前政策和建议政策下,该主帐号的成员访问权限均为未知,并且建议的更改可能会影响该主帐号的访问权限。

REST

调用 replays.results.list 方法时,响应包含 replayResults 列表。

每个重放结果都会描述一次访问尝试,如果尝试采用的政策已存在,则访问结果会有所不同。例如,以下重放结果表明,my-user@example.com 过去曾使用 resourcemanager.projects.update 权限在项目 my-project 中执行操作。但是,如果建议的政策落实到位,则会被拒绝。

{
  "accessTuple": {
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "resourcemanager.projects.update",
    "principal": "my-user@example.com"
  },
  "lastSeenDate": {
    "day": 15,
    "month": 1,
    "year": 2021
  },
  "diff": {
    "accessDiff": {
      "baseline": {
        "accessState": "GRANTED"
      },
      "simulated": {
        "accessState": "NOT_GRANTED"
      },
      "accessChange": "ACCESS_REVOKED"
    }
  }
}

每个重放结果包含以下字段:

  • accessTuple:与结果相关的访问尝试。此字段包括访问尝试所涉及的资源、权限和主帐号。

  • lastSeenDate:上次访问的日期。

  • diff.accessDiff error:如果访问尝试重放成功,则结果将包含diff.accessDiff字段,用于报告当前政策与建议的政策下的访问尝试结果之间的差异。如果重放尝试不成功,则重放结果将包含 error 字段以及错误说明。如需详细了解模拟错误,请参阅本页面上的错误

每个访问差异都具有以下组件:

  • baseline:使用当前政策时的访问结果。系统将其报告为以下值之一:GRANTEDNOT_GRANTEDUNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED。如果结果为 UNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED,则响应还会列出与未知信息关联的所有错误,以及与该错误关联的政策。如需详细了解 UNKNOWN 值,请参阅本页面上的未知结果
  • simulated:使用建议的政策时的访问结果。系统将其报告为以下值之一:GRANTEDNOT_GRANTEDUNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED。如果结果为 UNKNOWN_CONDITIONALUNKNOWN_INFO_DENIED,则响应还会列出与未知信息关联的所有错误,以及与该错误关联的政策。如需详细了解 UNKNOWN 值,请参阅本页面上的未知结果
  • accessChange:基准访问状态与模拟访问状态间的变化。如需查看可能的值的列表,请参阅下表:

    访问权限变更 详细信息
    ACCESS_REVOKED 该主帐号根据当前政策拥有访问权限,但在实施建议更改之后将会失去此访问权限。
    ACCESS_MAYBE_REVOKED

    出现此结果的原因如下:

    • 该主帐号在当前政策下拥有访问权限,但其在建议政策下的访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会失去此访问权限。
    ACCESS_GAINED 该主帐号根据当前政策无访问权限,但在实施建议更改之后将会获得此访问权限。
    ACCESS_MAYBE_GAINED

    出现此结果的原因如下:

    • 该主帐号根据当前政策无访问权限,但在实施建议更改之后,其访问权限为未知
    • 该主帐号在当前政策下的访问权限为未知,但在实施建议更改之后将会获得此访问权限。
    UNKNOWN_CHANGE 在当前政策和建议政策下,该主帐号的成员访问权限均为未知,并且建议的更改可能会影响该主帐号的访问权限。

未知结果

如果访问结果为未知,则表示政策模拟器没有足够的信息来全面评估访问尝试。

控制台

如果访问结果未知,则访问更改详细信息面板会报告其原因,以及它无法访问、评估的特定角色、政策、群组成员资格和条件。

导致结果未知的原因有多种:

  • 角色信息遭拒:运行模拟的主帐号无权查看正在模拟的一个或多个角色的角色详细信息。
  • 无法访问政策:运行模拟的主帐号无权获取模拟中涉及的一个或多个资源的 IAM 政策。
  • 成员资格信息遭拒:运行模拟的主帐号无权查看所提议的政策中包含的一个或多个组的成员。
  • 不支持的条件:正在测试的政策中有一个条件角色绑定。政策模拟器不支持条件,因此无法评估绑定。

gcloud

gcloud 工具中,模拟结果将报告结果在访问差异中未知的原因。

访问结果未知的原因包括:

  • UNKNOWN_INFO_DENIED:用户无权访问评估访问状态所需的信息。以下任何原因都可能导致这种情况:

    • 用户无权检索要模拟的政策,或者没有检索访问日志中资源的政策的权限。
    • 该用户无权查看群组成员资格。
    • 用户无法检索必要的角色信息。

    要了解缺少的信息,请参阅报告的访问权限状态后面的错误信息。

  • UNKNOWN_CONDITIONAL:正在测试的政策中有条件角色绑定。政策模拟器不支持条件,因此无法评估绑定。

如果结果未知,accessDiff政策字段(baselinesimulated )中包含一个errors一个字段,用于描述信息未知的原因,以及policies字段,其中列出了与错误相关联的政策。如需详细了解错误,请参阅本页面上的错误

REST

在 REST API 中,模拟结果将报告结果在访问差异中未知的原因。

访问结果未知的原因包括:

  • UNKNOWN_INFO_DENIED:用户无权访问评估访问状态所需的信息。以下任何原因都可能导致这种情况:

    • 用户无权检索要模拟的政策,或者没有检索访问日志中资源的政策的权限。
    • 该用户无权查看群组成员资格。
    • 用户无法检索必要的角色信息。

    要了解缺少的信息,请参阅报告的访问权限状态后面的错误信息。

  • UNKNOWN_CONDITIONAL:正在测试的政策中有条件角色绑定。政策模拟器不支持条件,因此无法评估绑定。

如果结果未知,accessDiff政策字段(baselinesimulated )中包含一个errors一个字段,用于描述信息未知的原因,以及policies字段,其中列出了与错误相关联的政策。如需详细了解错误,请参阅本页面上的错误

出错的实例数

政策模拟器还会报告模拟期间发生的任何错误。请务必查看这些错误,了解模拟中的潜在差距。

控制台

政策模拟器可能会报告多种类型的错误:

  • 操作错误:无法运行模拟。 政策模拟器在结果页面顶部报告操作错误。

    如果错误消息指出项目或组织中包含过多日志,导致无法运行模拟,则无法对资源运行模拟。

    如果您出于其他原因遇到此错误,请尝试重新运行模拟。如果仍无法运行模拟,请发送电子邮件至 policy-simulator-feedback@google.com。

  • 重放错误:单次访问尝试重放失败,因此政策模拟器无法确定访问尝试的结果是否会在建议政策下发生变化。

    Cloud Console 在过去 90 天的访问权限更改表中列出重放错误。每个错误的访问权限更改详情面板都包含一条错误消息,以帮助您了解问题以及发生错误时模拟的资源和权限。

  • 不受支持的资源类型错误:提议的政策会影响与不受支持的资源类型相关联的权限,政策模拟器无法模拟这种权限。

    政策模拟器会在模拟结果中列出这些权限,以便您了解它无法模拟的权限。

gcloud

gcloud 工具的模拟结果中,错误可能会出现在两个位置:

  • replayResult.error 字段:如果重放尝试失败,则政策模拟器会报告 replayResult.error 字段中的错误。如果重放结果包含此字段,则不包含 diff 字段。
  • replayResult.diff.accessDiff.policy-type.errors 字段中 policy-typebaselinesimulated。如果重放尝试成功,但结果为 UNKNOWN_INFO_DENIEDUNKNOWN_CONDITIONAL,则政策模拟器会报告此字段中结果未知的原因。

政策模拟器会生成以下类型的错误:

错误 错误代码 详细信息
GENERIC_INTERNAL_ERROR 13 由于内部错误,系统无法完成该请求。如需解决此问题,请尝试再次运行模拟。如果模拟仍然失败,请联系 policy-simulator-feedback@google.com。
INVALID_ACCESS_TUPLE 3 政策模拟器无法重放访问尝试,因为它包含无效的权限、资源名称或主帐号。
OUT_OF_RANGE_GROUP_TOO_LARGE 11 政策模拟器无法评估主帐号在群组中的成员资格,因为该群组的子群组过多。此错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_GROUP_MEMBERSHIP 7 政策模拟器无法评估用户的访问权限,因为调用者无权查看群组成员资格。此错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_IAM_POLICY 7 Policy Simulator 无法评估用户的访问权限,因为调用者无权检索 IAM 政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_IAM_ROLE 7 政策模拟器无法评估用户的访问权限,因为调用者无权在 IAM 角色中检索权限。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_PARENT_IAM_POLICY 7 Policy Simulator 无法评估用户的访问权限,因为调用者无权检索祖先资源的 IAM 政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
UNIMPLEMENTED_MEMBER_TYPE 12 访问元组包含政策模拟器不支持的主帐号类型。
UNIMPLEMENTED_MEMBER 12 访问元组包含政策模拟器不支持的主帐号。
UNIMPLEMENTED_CONDITION 12 访问元组包含政策模拟器不支持的条件。此类错误与 UNKNOWN_CONDITIONAL 访问权限更改相关。
LOG_SIZE_TOO_LARGE 8 该资源与过多的访问日志关联,因此政策模拟器无法运行模拟。如需了解详情,请参阅政策模拟器概念页面上的日志重放大小上限
UNSUPPORTED_RESOURCE 12

建议的政策会更改与不受支持的资源类型关联的权限。此错误显示在 replayResult.error 字段中,其中包含与不受支持的资源类型关联的权限列表。例如:


"error": {
  "code": 12,
  "details": [
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.create"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    },
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.setIamPolicy"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    },
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.get"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    }
  ],
  "message": "unsupported-permissions-error-message"
}

如需详细了解不受支持的资源类型,请参阅政策模拟器概念页面上的资源类型的支持级别

REST

在 REST API 模拟结果中,错误可能会出现在两个位置:

  • replayResult.error 字段:如果重放尝试失败,则政策模拟器会报告 replayResult.error 字段中的错误。如果重放结果包含此字段,则不包含 diff 字段。
  • replayResult.diff.accessDiff.policy-type.errors 字段中 policy-typebaselinesimulated。如果重放尝试成功,但结果为 UNKNOWN_INFO_DENIEDUNKNOWN_CONDITIONAL,则政策模拟器会报告此字段中结果未知的原因。

政策模拟器会生成以下类型的错误:

错误 错误代码 详细信息
GENERIC_INTERNAL_ERROR 13 由于内部错误,系统无法完成该请求。如需解决此问题,请尝试再次运行模拟。如果模拟仍然失败,请联系 policy-simulator-feedback@google.com。
INVALID_ACCESS_TUPLE 3 政策模拟器无法重放访问尝试,因为它包含无效的权限、资源名称或主帐号。
OUT_OF_RANGE_GROUP_TOO_LARGE 11 政策模拟器无法评估主帐号在群组中的成员资格,因为该群组的子群组过多。此错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_GROUP_MEMBERSHIP 7 政策模拟器无法评估用户的访问权限,因为调用者无权查看群组成员资格。此错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_IAM_POLICY 7 Policy Simulator 无法评估用户的访问权限,因为调用者无权检索 IAM 政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_IAM_ROLE 7 政策模拟器无法评估用户的访问权限,因为调用者无权在 IAM 角色中检索权限。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
PERMISSION_DENIED_ON_PARENT_IAM_POLICY 7 Policy Simulator 无法评估用户的访问权限,因为调用者无权检索祖先资源的 IAM 政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。
UNIMPLEMENTED_MEMBER_TYPE 12 访问元组包含政策模拟器不支持的主帐号类型。
UNIMPLEMENTED_MEMBER 12 访问元组包含政策模拟器不支持的主帐号。
UNIMPLEMENTED_CONDITION 12 访问元组包含政策模拟器不支持的条件。此类错误与 UNKNOWN_CONDITIONAL 访问权限更改相关。
LOG_SIZE_TOO_LARGE 8 该资源与过多的访问日志关联,因此政策模拟器无法运行模拟。如需了解详情,请参阅政策模拟器概念页面上的日志重放大小上限
UNSUPPORTED_RESOURCE 12

建议的政策会更改与不受支持的资源类型关联的权限。此错误显示在 replayResult.error 字段中,其中包含与不受支持的资源类型关联的权限列表。例如:


"error": {
  "code": 12,
  "details": [
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.create"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    },
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.setIamPolicy"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    },
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "domain": "policysimulator.googleapis.com",
      "metadata": {
        "permission": "storage.objects.get"
      },
      "reason": "UNSUPPORTED_RESOURCE"
    }
  ],
  "message": "unsupported-permissions-error-message"
}

如需详细了解不受支持的资源类型,请参阅政策模拟器概念页面上的资源类型的支持级别

应用模拟政策更改

如需应用模拟政策更改,请按照以下步骤操作:

控制台

  1. 点击应用建议的更改

  2. 在确认对话框中,点击应用以确认更改。

gcloud

使用 set-iam-policy 命令,并提供包含要应用的模拟政策的 JSON 文件的路径:

gcloud resource-type set-iam-policy resource-id filepath

请提供以下值:

  • resource-type:您要管理其政策的资源类型。例如 projects
  • resource-id:您要更新其政策的资源的 ID。例如 my-project
  • filepath:包含更新后政策的文件的路径。

响应中包含更新后的政策。 如果您将 IAM 政策视为代码并将其存储在版本控制系统中,则应存储 gcloud 工具返回的政策,而不是包含模拟政策的 JSON 文件。

REST

将建议的政策设置为资源的新政策。

Resource Manager API 的 projects.setIamPolicy 方法会将请求中的政策设置为项目的新 IAM 政策。

在使用任何请求数据之前,请先进行以下替换:

  • PROJECT_ID:您的 Google Cloud 项目 ID。 项目 ID 是字母数字字符串,例如 my-project
  • POLICY:您要设置的政策的 JSON 格式。如需详细了解政策的格式,请参阅政策参考

HTTP 方法和网址:

POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy

请求 JSON 正文:

{
  "policy": {
    POLICY
  }
}

如需发送您的请求,请展开以下选项之一:

响应中包含更新后的政策。


保存模拟结果

如果您使用的是 gcloud 工具,则可以将政策模拟器结果另存为 JSON、YAML 或 CSV 文件。

另存为 JSON 或 YAML

如需将模拟结果另存为 JSON 或 YAML 文件,请在运行模拟时将以下标志添加到 replay-recent-access 命令:

--output=output-format > filename

替换以下值:

  • output-format:导出文件的语言,jsonyaml
  • filename:导出文件的名称。

正在另存为 CSV

要保存 CSV 文件,请在运行模拟时将以下标志添加到 replay-recent-access 命令:

--flatten="diffs[]" --format=csv(output-fields) > filename

替换以下值:

  • output-fields:要包含在导出结果中的字段的英文逗号分隔列表。例如 diffs.accessTuple.principal, diffs.accessTuple.permission
  • filename:导出文件的名称。

或者,您可以将其他字段(例如 errors[])添加到 --flatten 标志中。将字段添加到 --flatten 标志可让这些字段中的元素在 CSV 文件中以单独的行列出。

以下示例 replay-recent-access 命令将模拟结果最重要的字段保存为 CSV 文件 simulation-results.csv

gcloud iam simulator replay-recent-access --flatten="diffs[]" \
    --format="csv(diffs.accessTuple.principal, diffs.accessTuple.permission, \
    diffs.accessTuple.fullResourceName, diffs.diff.accessDiff.accessChange, \
    diffs.diff.accessDiff.baseline.accessState, \
    diffs.diff.accessDiff.simulated.accessState)" \
    //cloudresourcemanager.googleapis.com/projects/my-project \
    proposed-policy.json > simulation-results.csv

此示例模拟项目 my-projectproposed-policy.json 并将结果另存为 simulation-results.csv。此 CSV 文件包含以下字段:主帐号、权限、资源、访问权限更改、基准访问状态和模拟访问状态。

如需详细了解如何使用 gcloud 工具进行格式设置,请参阅格式

后续步骤