本页介绍了如何使用以下代码模拟对允许政策的更改: Identity and Access Management 的 Policy Simulator 允许政策。还说明了如何 如何解读模拟结果,以及如何应用模拟允许 政策。
准备工作
-
Enable the Policy Simulator and Resource Manager APIs.
- 可选:了解政策模拟器的工作原理。
所需权限
在模拟对允许政策的更改之前,您需要确保您拥有适当的权限。运行模拟需要某些权限;其他权限则不需要,但有助于您从模拟中获得最完整的结果。
如需详细了解 Identity and Access Management (IAM) 角色,请参阅 了解角色。
必需的目标资源权限
模拟的目标资源是要模拟其允许政策的资源。
如需获取运行模拟所需的权限, 请让管理员授予您 针对目标资源的以下 IAM 角色:
-
Cloud Asset Viewer (
roles/cloudasset.viewer
) -
Simulator Admin (
roles/policysimulator.admin
) -
安全审核者 (
roles/iam.securityReviewer
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
这些预定义角色包含 运行模拟所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
运行模拟需要以下权限:
-
cloudasset.assets.searchAllResources
-
policysimulator.replays.run
service.resource.getIamPolicy
,其中resource
是目标资源的资源类型,service
是拥有该资源的 Google Cloud 服务的名称。
必需的主机资源权限
模拟的托管资源是创建并运行模拟的项目、文件夹或组织。主机资源不需要与目标资源以任何方式相关。
设置主机资源的方式取决于您使用的平台。
控制台
主机资源是资源选择器中显示的项目、文件夹或组织。
如需更改主机资源,请在资源选择器中选择其他项目、文件夹或组织。
gcloud
主机资源是当前配额项目。如需设置配额项目,请使用 gcloud auth application-default set-quota-project
命令。
REST
每次发送请求时,您手动指定主机资源。如需了解详情,请参阅本页面上的模拟政策更改。
如需获取运行模拟所需的权限,
请让管理员授予您
Simulator Admin (roles/policysimulator.admin
) IAM 角色。
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
此预定义角色包含 运行模拟所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
运行模拟需要以下权限:
-
policysimulator.replayResults.list
-
policysimulator.replays.create
-
policysimulator.replays.get
建议的权限数
为了获得最佳的模拟结果,我们建议您拥有特定的 IAM 和 Google Workspace 权限。如果您没有以上部分或全部权限,则仍可以运行模拟。但是,运行没有这些权限的模拟可能会导致未知的访问权限更改数量增加,因为您可能无法检索可能影响模拟结果的信息。
建议的 IAM 权限
我们建议您在运行模拟时拥有 Organization Security Reviewer 角色 (roles/iam.securityReviewer
)。或者,如果您已拥有 Security Admin 角色 (roles/iam.securityAdmin
),则无需授予任何其他角色。
这些角色可为您提供以下权限,帮助您从模拟中获得最完整的结果:
- 定义了自定义角色的任何相关项目、文件夹或组织的
iam.roles.get
和iam.roles.list
权限。如果某个项目、文件夹或组织是您要模拟其允许政策的资源的祖先或后代,则该项目、文件夹或组织是相关的。 service.resource.getIamPolicy
,其中resource
是可以具有允许政策的资源类型的名称,service
是拥有该资源的 Google Cloud 服务的名称。在运行模拟时,我们建议您对每个符合以下条件的资源拥有此权限:
例如,假设您想为 项目。如果访问日志包含对某请求的访问尝试, Cloud Storage 存储桶,则您需要
storage.buckets.getIamPolicy
权限。如果项目 具有允许政策的父级文件夹,那么您还需要resourcemanager.folders.getIamPolicy
权限。
建议的 Google Workspace 权限
我们建议您有权检索原始允许政策和建议的允许政策中每个 Google 群组的群组成员资格信息。
Google Workspace 超级用户和群组管理员通常有权查看群组成员资格。如果您不是超级用户或群组管理员,请让 Google Workspace 管理员执行以下操作:创建自定义 Google Workspace 管理员角色,其中包含groups.read
权限(位于Admin API 权限),然后将其授予您。这样,您就可以查看网域中所有群组的成员资格,并更有效地模拟对允许政策的更改。
模拟政策更改
按照以下步骤模拟对允许政策的更改。
控制台
以下示例演示了如何模拟对项目的允许政策的更改。但是,您可以模拟对任何具有允许政策的资源的允许政策的更改。
修改主账号的权限,然后点击模拟,而不是点击测试更改:
gcloud
如需模拟对允许政策的更改,请遵循读取-修改-写入模式,但要模拟允许政策而不是写入允许政策。
通过运行以下命令来读取当前允许政策:
gcloud resource-type get-iam-policy resource-id --format=format > filepath
替换以下值:
resource-type
:您要模拟其允许政策的资源的类型。例如projects
。resource-id
:允许其访问的资源的 ID 政策例如my-project
。format
:响应的格式。使用值json
或yaml
。filepath
:指向允许政策的新输出文件的路径。
例如,以下命令会以 JSON 格式获取项目
my-project
的允许政策,并将其保存到用户的主目录:gcloud projects get-iam-policy my-project --format=json > ~/policy.json
修改由
get-iam-policy
命令返回的 JSON 或 YAML 允许政策 以反映您要模拟的更改。您可以对允许政策进行多种更改。例如,您可以在角色绑定中添加或移除主账号,或者从允许政策中移除角色绑定。
运行以下命令以模拟对允许政策的更改:
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
:响应的格式。例如json
或yaml
。
几分钟后,该命令会输出重放结果的列表,说明主账号的访问权限在应用建议的允许政策后会如何变化。这些结果还列出了模拟期间出现的任何错误,包括由于不受支持的资源类型而导致的任何错误。
请参阅此页面上的了解政策模拟器结果,了解如何读取结果。如需了解如何保存模拟结果而不是输出结果,请参阅保存模拟结果。
以下是涉及的允许政策模拟的响应示例 用户
my-user@example.com
。在这种情况下,如果建议的更改 应用后,my-user@example.com
可能不再拥有resourcemanager.projects.list
和resourcemanager.projects.get
项目“my-project
”的权限,因此系统将不再对 项目的resourcemanager.projects.update
权限my-project
:[ { "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
如需模拟对允许政策的更改,请遵循读取-修改-写入模式,但不要写入允许政策,而是创建并运行模拟。
读取资源的允许政策。
要获取项目的允许政策,请使用 Resource Manager API 的
projects.getIamPolicy
方法。在使用任何请求数据之前,请先进行以下替换:
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" ] } ] }
修改返回的允许政策,以反映您要模拟的更改。
您可以对允许政策进行多种更改。例如,您可以在角色绑定中添加或移除主账号,或者从允许政策中移除角色绑定。
使用修改后的允许政策创建模拟或重放。
要为项目、文件夹或组织创建重放,请使用 Policy Simulator API 的
replays.create
方法。在使用任何请求数据之前,请先进行以下替换:
-
HOST_RESOURCE_TYPE
:将托管 Replay 的资源类型。此值必须为projects
、folders
或organizations
。 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
对。 PROJECT_ID
:您的 Google Cloud 项目 ID。项目 ID 是字母数字字符串,例如my-project
。
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" } }
-
轮询
operations.get
方法,直到重放完成。如要轮询操作,我们建议您重复调用
operations.get
方法,直到响应包含字段"done": true
和name
字段以及已完成的重放的名称。使用截断指数退避算法在每个请求之间引入延迟。如需获取重放的状态,请使用 Policy Simulator API 的
operations.get
方法。在使用任何请求数据之前,请先进行以下替换:
OPERATION_NAME
:重放操作的名称,包括operations
前缀。从replays.create
响应的name
字段中复制此值。例如:operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8
PROJECT_ID
:您的 Google Cloud 项目 ID。项目 ID 是字母数字字符串,例如my-project
。
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 } } } } }
获取 Replay 的结果。
如需获取重放的结果,请使用 Policy Simulator 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
:可选。此方法之前的响应中返回的分页令牌。如果已指定,则结果列表将从上一个请求结束的位置开始。PROJECT_ID
:您的 Google Cloud 项目 ID。项目 ID 是字母数字字符串,例如my-project
。
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-project
的resourcemanager.projects.list
和resourcemanager.projects.get
权限,并且当然不再具有项目my-project
的resourcemanager.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" }
如果现有允许政策与模拟的允许政策之间的访问权限没有变化,则请求会返回空列表 (
{}
)。-
了解 Policy Simulator 结果
Policy Simulator 会将建议的对允许政策的更改的影响报告为访问权限更改列表。每次访问权限更改表示过去 90 天内的一次访问尝试,在建议的允许政策下产生的结果与在当前允许政策下产生的结果不同。
政策模拟器还列出了模拟期间发生的所有错误,从而帮助您识别模拟中的潜在差距。
这些更改和错误的呈现方式取决于您使用的平台。
控制台
政策模拟器结果页面会在几个不同的部分中显示模拟结果:
政策更改:此部分列出了您要建议其更改的允许政策的资源、您建议移除的角色,以及您建议添加的角色。
此部分还包含查看政策差异按钮。如果您点击此按钮,则可以查看资源的允许政策在建议的更改前后是什么情况。
权限更改:本部分包含已移除和已添加权限的计数,描述主账号的权限在您应用建议的更改时会如何变化。这些权限数量是通过将主账号当前角色中的权限与主账号建议角色(忽略继承角色)中的权限进行比较而计算得出的。
此部分还包含查看权限差异按钮。如果您点击此按钮,则可以查看主账号当前角色和建议角色中的权限的并列比较结果。
过去 90 天内的访问权限更改:此部分展示了过去 90 天内哪些访问尝试在建议的允许政策和当前允许政策下具有不同的结果。此部分包含访问权限更改的摘要以及具有更详细结果的表。
访问权限更改摘要列出了每种访问权限更改的次数、错误和未知结果的数量,以及在建议的允许政策和当前允许政策下具有相同结果的访问尝试次数。此摘要还展示了无法模拟的权限数量。如需了解详情,请参阅本页面上的错误。
此部分还包含访问权限更改表。此表列出了过去 90 天内在建议的允许政策和当前允许政策下具有不同结果的每次访问尝试。每个条目都包含主账号尝试访问的资源、请求的日期、发出请求的主账号、请求中的权限,以及建议的允许政策下的访问状态与当前允许政策下的访问状态的对比。
访问权限有以下几种类型:
访问权限变更 详细信息 访问权限已被撤消 主账号在当前允许政策下拥有访问权限,但在实施建议的更改之后将不再拥有访问权限。 访问权限可能已被撤消 出现此结果的原因如下:
已获得访问权限 主账号在当前允许政策下没有访问权限,但在实施建议的更改之后将拥有访问权限。 可能已获得访问权限 出现此结果的原因如下:
访问权限未知 主账号在当前允许政策和建议的允许政策下的访问权限均为未知,并且建议的更改可能会影响主账号的访问权限。 错误 模拟过程中发生错误。 如需查看有关访问权限更改的其他详细信息,请点击访问权限更改。此操作会打开访问权限更改详细信息面板,其中显示有关访问权限更改的其他信息,包括主账号的现有访问权限、主账号的建议访问权限以及有关访问权限更改结果的其他详细信息。
gcloud
使用 replay-recent-access
命令时,gcloud CLI 的响应包含 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
:使用当前允许政策时的访问结果。系统将其报告为以下值之一:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果结果为UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,则响应还会列出与未知信息关联的任何错误,以及与该错误关联的允许政策。如需详细了解UNKNOWN
值,请参阅本页面上的未知结果。simulated
:使用建议的允许政策时的访问结果。该访问结果会报告为以下值之一:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果结果为UNKNOWN_CONDITIONAL
或UNKNOWN_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
:使用当前允许政策时的访问结果。系统将其报告为以下值之一:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果结果为UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,则响应还会列出与未知信息关联的任何错误,以及与该错误关联的允许政策。如需详细了解UNKNOWN
值,请参阅本页面上的未知结果。simulated
:使用建议的允许政策时的访问结果。该访问结果会报告为以下值之一:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果结果为UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,则响应还会列出与未知信息关联的任何错误,以及与该错误关联的允许政策。如需详细了解UNKNOWN
值,请参阅本页面上的未知结果。accessChange
:基准访问状态与模拟访问状态间的变化。如需查看可能的值的列表,请参阅下表:访问权限变更 详情 ACCESS_REVOKED
主账号在当前允许政策下拥有访问权限,但在实施建议的更改之后将不再拥有访问权限。 ACCESS_MAYBE_REVOKED
出现此结果的原因如下:
ACCESS_GAINED
主账号在当前允许政策下没有访问权限,但在实施建议的更改之后将拥有访问权限。 ACCESS_MAYBE_GAINED
出现此结果的原因如下:
UNKNOWN_CHANGE
主账号在当前允许政策和建议的允许政策下的访问权限均为未知,并且建议的更改可能会影响主账号的访问权限。
未知结果
如果访问结果为未知,则表示政策模拟器没有足够的信息来全面评估访问尝试。
控制台
如果访问结果未知,则访问权限更改详细信息面板会报告未知的原因,以及无法访问或评估的特定角色、允许政策、群组成员资格和条件。
导致结果未知的原因有多种:
- 角色信息遭拒:运行模拟的主账号无权查看正在模拟的一个或多个角色的角色详细信息。
- 无法访问政策:运行模拟的主账号无权获取模拟中涉及的一个或多个资源的允许政策。
- 成员资格信息被拒:运行模拟的主账号无权查看建议的允许政策中包含的一个或多个群组的成员。
- 条件不受支持:要测试的允许政策中存在条件角色绑定。Policy Simulator 不支持条件,因此无法评估绑定。
gcloud
在 gcloud CLI 中,模拟结果将报告结果在访问差异中未知的原因。
访问结果未知的原因包括:
UNKNOWN_INFO_DENIED
:用户无权访问评估访问状态所需的信息。以下任何原因都可能导致这种情况:- 用户无权检索要模拟的允许政策,或者无权检索访问日志中的资源的允许政策。
- 该用户无权查看群组成员资格。
- 用户无法检索必要的角色信息。
要了解缺少的信息,请参阅报告的访问权限状态后面的错误信息。
UNKNOWN_CONDITIONAL
:要测试的允许政策中存在条件角色绑定。Policy Simulator 不支持条件,因此无法评估绑定。
如果结果未知,则允许政策的字段(baseline
或 simulated
)包含 errors
字段(描述信息未知的原因)和 policies
字段(列出与错误关联的允许政策)。如需详细了解错误,请参阅本页面上的错误。
REST
在 REST API 中,模拟结果将报告结果在访问差异中未知的原因。
访问结果未知的原因包括:
UNKNOWN_INFO_DENIED
:用户无权访问评估访问状态所需的信息。以下任何原因都可能导致这种情况:- 用户无权检索要模拟的允许政策,或者无权检索访问日志中的资源的允许政策。
- 该用户无权查看群组成员资格。
- 用户无法检索必要的角色信息。
要了解缺少的信息,请参阅报告的访问权限状态后面的错误信息。
UNKNOWN_CONDITIONAL
:要测试的允许政策中存在条件角色绑定。Policy Simulator 不支持条件,因此无法评估绑定。
如果结果未知,则允许政策的字段(baseline
或 simulated
)包含 errors
字段(描述信息未知的原因)和 policies
字段(列出与错误关联的允许政策)。如需详细了解错误,请参阅本页面上的错误。
出错的实例数
政策模拟器还会报告模拟期间发生的任何错误。请务必查看这些错误,了解模拟中的潜在差距。
控制台
政策模拟器可能会报告多种类型的错误:
操作错误:无法运行模拟。 政策模拟器在结果页面顶部报告操作错误。
如果错误消息指出项目或组织中包含过多日志,导致无法运行模拟,则无法对资源运行模拟。
如果您出于其他原因遇到此错误,请尝试重新运行模拟。如果仍无法运行模拟,请发送电子邮件至 policy-simulator-feedback@google.com。
重放错误:单次访问尝试重放失败,因此 Policy Simulator 无法确定访问尝试的结果是否会在建议的允许政策下更改。
Google Cloud 控制台会在以下位置列出重放错误: 过去 90 天表格中。每个错误的访问权限更改详情面板都包含一条错误消息,以帮助您了解问题以及发生错误时模拟的资源和权限。
不受支持的资源类型错误:建议的允许政策会影响与不受支持的资源类型相关联的权限,Policy Simulator 无法模拟这种权限。
政策模拟器会在模拟结果中列出这些权限,以便您了解它无法模拟的权限。
gcloud
在 gcloud CLI 的模拟结果中,错误可能会出现在两个位置:
replayResult.error
字段:如果重放尝试失败,则政策模拟器会报告replayResult.error
字段中的错误。如果重放结果包含此字段,则不包含diff
字段。replayResult.diff.accessDiff.policy-type.errors
字段中 policy-type 为baseline
或simulated
。如果重放尝试成功,但结果为UNKNOWN_INFO_DENIED
或UNKNOWN_CONDITIONAL
,则政策模拟器会报告此字段中结果未知的原因。
政策模拟器会生成以下类型的错误:
错误 | 错误代码 | 详细信息 |
---|---|---|
GENERIC_INTERNAL_ERROR |
13 | 由于内部错误,系统无法完成该请求。如需解决此问题,请尝试再次运行模拟。如果模拟仍然失败,请联系 policy-simulator-feedback@google.com。 |
INVALID_ACCESS_TUPLE |
3 | Policy Simulator 无法重放 因为其中包含无效的权限、资源名称 或主账号。 |
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 无法评估用户的访问权限,因为调用者无权检索允许政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。 |
PERMISSION_DENIED_ON_IAM_ROLE |
7 | 政策模拟器无法评估用户的访问权限,因为调用者无权在 IAM 角色中检索权限。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。 |
PERMISSION_DENIED_ON_PARENT_IAM_POLICY |
7 | Policy Simulator 无法评估用户的访问权限,因为调用者无权检索祖先资源的允许政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关联。 |
UNIMPLEMENTED_MEMBER_TYPE |
12 | 访问元组包含政策模拟器不支持的主账号类型。 |
UNIMPLEMENTED_MEMBER |
12 | 访问元组包含政策模拟器不支持的主账号。 |
UNIMPLEMENTED_CONDITION |
12 | 访问元组包含政策模拟器不支持的条件。此类错误与 UNKNOWN_CONDITIONAL 访问权限更改相关。 |
LOG_SIZE_TOO_LARGE |
8 | 该资源与过多的访问日志关联,因此政策模拟器无法运行模拟。请参阅 日志重放大小上限 。 |
UNSUPPORTED_RESOURCE |
12 |
建议的允许政策会更改与不受支持的资源类型相关联的权限。此错误显示在 "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-type 为baseline
或simulated
。如果重放尝试成功,但结果为UNKNOWN_INFO_DENIED
或UNKNOWN_CONDITIONAL
,则政策模拟器会报告此字段中结果未知的原因。
政策模拟器会生成以下类型的错误:
错误 | 错误代码 | 详细信息 |
---|---|---|
GENERIC_INTERNAL_ERROR |
13 | 由于内部错误,系统无法完成该请求。如需解决此问题,请尝试再次运行模拟。如果模拟仍然失败,请联系 policy-simulator-feedback@google.com。 |
INVALID_ACCESS_TUPLE |
3 | Policy Simulator 无法重放 因为其中包含无效的权限、资源名称 或主账号。 |
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 无法评估用户的访问权限,因为调用者无权检索允许政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。 |
PERMISSION_DENIED_ON_IAM_ROLE |
7 | 政策模拟器无法评估用户的访问权限,因为调用者无权在 IAM 角色中检索权限。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关。 |
PERMISSION_DENIED_ON_PARENT_IAM_POLICY |
7 | Policy Simulator 无法评估用户的访问权限,因为调用者无权检索祖先资源的允许政策。此类错误与 UNKNOWN_INFO_DENIED 访问权限更改相关联。 |
UNIMPLEMENTED_MEMBER_TYPE |
12 | 访问元组包含政策模拟器不支持的主账号类型。 |
UNIMPLEMENTED_MEMBER |
12 | 访问元组包含政策模拟器不支持的主账号。 |
UNIMPLEMENTED_CONDITION |
12 | 访问元组包含政策模拟器不支持的条件。此类错误与 UNKNOWN_CONDITIONAL 访问权限更改相关。 |
LOG_SIZE_TOO_LARGE |
8 | 该资源与过多的访问日志关联,因此政策模拟器无法运行模拟。请参阅 日志重放大小上限 。 |
UNSUPPORTED_RESOURCE |
12 |
建议的允许政策会更改与不受支持的资源类型相关联的权限。此错误显示在 "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" } 如需详细了解不受支持的资源类型,请参阅政策模拟器概念页面上的资源类型的支持级别。 |
应用模拟政策更改
如需应用对允许政策的模拟更改,请按照以下步骤操作:
控制台
点击应用建议的更改。
在确认对话框中,点击应用以确认更改。
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 CLI 返回的允许政策,而不是包含模拟的允许政策的 JSON 文件。
REST
将建议的允许政策设置为资源的新允许政策。
要将请求中的允许政策设置为项目的新允许政策,请使用 Resource Manager API 的
projects.setIamPolicy
方法。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_ID
:您的 Google Cloud 项目 ID。项目 ID 是字母数字字符串,例如my-project
。POLICY
:您要设置的政策的 JSON 格式。如需详细了解政策的格式,请参阅政策参考文档。
HTTP 方法和网址:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy
请求 JSON 正文:
{ "policy": { POLICY } }
如需发送您的请求,请展开以下选项之一:
响应包含更新后的允许政策。
<ph type="x-smartling-placeholder">保存模拟结果
如果您使用的是 gcloud CLI,则可以将政策模拟器结果另存为 JSON、YAML 或 CSV 文件。
保存为 JSON 或 YAML
如需将模拟结果另存为 JSON 或 YAML 文件,请在运行模拟时将以下标志添加到 replay-recent-access
命令:
--output=output-format > filename
替换以下值:
output-format
:导出文件的语言,json
或yaml
。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-project
的 proposed-policy.json
并将结果另存为 simulation-results.csv
。此 CSV 文件包含以下字段:主账号、权限、资源、访问权限更改、基准访问状态和模拟访问状态。
如需详细了解如何使用 gcloud CLI 进行格式设置,请参阅格式。
后续步骤
- 了解如何排查现有主账号的访问权限的问题。
- 了解如何使用角色建议强制执行最小权限。