排查 IAM 权限问题

借助适用于 IAM 的 Policy Troubleshooter,您可以了解用户有权访问资源或无权调用 API 的原因。 给定电子邮件地址、资源和权限后,政策问题排查工具会检查适用于该资源的所有允许和拒绝政策。然后,它会使用这些政策来判断主帐号是否具有该权限。此外,还列出了政策中的角色绑定和拒绝规则,并说明它们如何影响主帐号的访问权限。

您可以使用 Google Cloud 控制台、Google Cloud CLI 或 REST API 访问 Policy Troubleshooter。对于简单查询,使用 Google Cloud 控制台通常速度最快。对于更复杂的场景,请考虑使用 gcloud CLI 或 REST API。

准备工作

  • 启用 Policy Troubleshooter API。

    启用 API

所需权限

如需全面排查主帐号访问权限问题,您需要以下权限。

拥有排查各个主账号访问权限问题的权限

Policy Troubleshooter 根据允许政策、拒绝政策和您有权查看的角色来分析主账号对资源的访问权限。如果您无权查看适用于资源的政策,或者无权查看自定义角色,则可能无法确定主帐号是否具有访问权限。

如需获取排查主帐号访问权限问题所需的权限,请让管理员授予您组织的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

排查群组成员访问权限问题的权限

如果您的允许和拒绝政策包含群组,您需要拥有 Google Workspace Admin API 权限 groups.read,才能排查各个群组成员的访问权限问题。超级用户和群组管理员会自动获得此权限。如需向不是超级用户或群组管理员的用户授予此权限,请创建自定义 Google Workspace 管理员角色,该角色包含 groups.read 权限(位于 Admin API 权限下),并将该角色授予该用户。

如果您没有这些权限,则包含群组或网域的角色绑定和拒绝规则的访问结果为 Unknown,除非角色绑定或拒绝规则也明确包含主帐号。

排查网域管理员访问权限问题的权限

如果您的允许和拒绝政策包含 Google Workspace 帐号或 Cloud Identity 网域,则您必须是网域管理员才能排查个别网域成员的访问权限问题。

如果您没有这些权限,则包含群组或网域的角色绑定和拒绝规则的访问结果为 Unknown,除非角色绑定或拒绝规则也明确包含主帐号。

排查权限问题

如需排查访问权限问题,您需要以下信息:

  • 主账号:要检查的电子邮件地址。电子邮件地址必须引用用户或服务账号。不支持其他类型的主帐号,包括群组、网域、员工身份和工作负载身份。
  • 资源:资源的完整名称。例如,如需检查项目 my-project,请输入 //cloudresourcemanager.googleapis.com/projects/my-project。对于其他类型的资源,请参阅完整资源名称示例
  • 权限:要检查的权限。如果您使用 Google Cloud 控制台,它会在您输入时显示建议列表。有关权限的完整列表,请查看权限参考

控制台

如要排查访问权限问题,请执行以下操作:

  1. 在 Google Cloud 控制台中,前往 Policy Troubleshooter 页面。

    转到政策问题排查工具

  2. 输入您要检查其访问权限的主账号的电子邮件地址。

  3. 输入要检查的资源的完整资源名称。

    如果您不知道完整的资源名称,请执行以下操作之一:

    • 如果您要排查项目、文件夹或组织的访问权限问题,请开始输入以查看自动补全选项。
    • 如需排查其他资源类型的访问权限问题,请点击浏览打开资源搜索对话框,然后搜索相应资源:

      1. 选择范围框中,选择要在其中进行搜索的项目、文件夹或组织。
      2. Resource type 框中,选择您要搜索的资源类型。
      3. 搜索资源框中,输入资源名称的一部分。
      4. 在结果部分,选择要检查的资源。
      5. 点击选择以选择资源并关闭对话框。
  4. 输入要检查的权限。

    如果您不知道完整的权限名称,请开始输入以查看自动补全选项。

  5. 可选:要检查多项资源和权限,请选择添加其他权限对,并重复上一步骤。

  6. 点击检查访问权限

gcloud

如需了解主帐号拥有或不具有 IAM 权限的原因,请使用 gcloud policy-troubleshoot iam 命令。

在使用下面的命令数据之前,请先进行以下替换:

  • EMAIL:您要排查其权限问题的主账号的电子邮件地址。
  • RESOURCE:向其授予权限的资源。
  • PERMISSION:您要排查其问题的权限。

执行 gcloud policy-troubleshoot iam 命令:

Linux、macOS 或 Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION

Windows (PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION

Windows (cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION

您应该会收到类似如下所示的响应:

{
  "accessTuple": {
    "conditionContext": {
      "destination": {},
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ],
      "request": {},
      "resource": {}
    },
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "principal": "user1@example.com"
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "policy": {
          "bindings": [
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/compute.viewer"
            },
            {
              "members": [
                "user:user2@example.com"
              ],
              "role": "roles/owner"
            },
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/resourcemanager.organizationAdmin"
            },
          ],
          "etag": "BwX5/L9Vbg4=",
          "version": 3
        },
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "createTime": "2023-04-18T07:15:47.702191Z",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "kind": "DenyPolicy",
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ],
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "updateTime": "2023-04-18T07:15:47.702191Z",
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "ruleExplanations": [
              {
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ]
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "permissionDeniable": true,
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "overallAccessState": "CANNOT_ACCESS"
}

REST

如需了解主帐号具有或不具有 IAM 权限的原因,请使用 Policy Troubleshooter API 的 iam.troubleshoot 方法。

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

  • EMAIL:您要排查其权限问题的主账号的电子邮件地址。
  • RESOURCE:向其授予权限的资源。
  • PERMISSION:您要排查其问题的权限。
  • PROJECT_ID:您要用于发出请求的项目的 ID。项目 ID 是字母数字字符串,例如 my-project

HTTP 方法和网址:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

请求 JSON 正文:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION"
  }
}

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

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

{
  "overallAccessState": "CANNOT_ACCESS",
  "accessTuple": {
    "principal": "user1@example.com",
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "conditionContext": {
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ]
    }
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH",
        "policy": {
          "version": 3,
          "etag": "BwX5/L9Vbg4=",
          "bindings": [
            {
              "role": "roles/compute.viewer",
              "members": [
                "user:user1@example.com"
              ]
            },
            {
              "role": "roles/owner",
              "members": [
                "user:user2@example.com"
              ]
            },
            {
              "role": "roles/resourcemanager.organizationAdmin",
              "members": [
                "user:user1@example.com"
              ]
            },
          ]
        }
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "kind": "DenyPolicy",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "createTime": "2023-04-18T07:15:47.702191Z",
              "updateTime": "2023-04-18T07:15:47.702191Z",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ]
            },
            "ruleExplanations": [
              {
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ],
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_HIGH",
    "permissionDeniable": true
  }
}

了解问题排查工具结果

控制台

结果页面包含以下信息:

评估详情

评估详情部分包含您要排查的访问权限的摘要,包括指定的主帐号、资源和权限。如需对多个资源权限对进行问题排查,您可以使用访问权限评估列表在它们之间切换。

政策详情

政策详情部分详细介绍了相关的允许和拒绝政策如何影响主帐号的访问权限。

相关的允许和拒绝政策包括:

  • 资源的允许政策
  • 资源的拒绝政策(如果有)
  • 资源的父级项目、文件夹和组织的允许政策(如有)
  • 资源的父级项目、文件夹和组织的拒绝政策(如果有)

由于政策沿用,父级项目、文件夹和组织的允许和拒绝政策是相关的。将允许或拒绝政策附加到项目、文件夹或组织时,该政策也适用于该项目、文件夹或组织内的所有资源。

例如,如果组织的拒绝政策指出主账号无法使用特定权限,则主账号无法将该权限用于组织内的任何资源。即使该组织内的文件夹和项目具有更宽松的拒绝政策,或向主帐号授予权限的允许政策,此规则也适用。

同样,如果项目的允许政策为主账号授予特定权限,则主账号对项目内的任何资源都拥有该权限,前提是他们未被拒绝该权限。

政策详情部分包含以下部分:

访问状态

访问状态部分根据相关的 IAM 允许和拒绝政策简要总结了主账号的访问权限。此摘要包含拒绝政策的影响、允许政策的影响,以及基于相关拒绝和允许政策的最终访问权限结果。

拒绝政策

拒绝政策部分中,您可以查看所有相关的拒绝政策,确定拒绝主账号访问权限的拒绝规则,并了解拒绝规则拒绝或不拒绝主账号权限的原因。

具有拒绝政策的资源窗格列出了所有相关的拒绝政策,按政策附加的资源进行整理。每项拒绝政策旁边都有一项访问权限评估。此评估仅适用于该拒绝政策,不反映来自继承的政策的任何访问权限。如果您无权查看某个资源的拒绝政策,则资源列表不包含该资源或其拒绝政策。

如需查看这些拒绝政策中的相关拒绝规则,请点击拒绝政策。如需查看资源拒绝政策中的所有拒绝规则,请点击相应资源。拒绝规则会显示在拒绝规则窗格中。此窗格包含一个表,其中包含针对您选择的资源或拒绝政策所查询的主账号或权限的所有拒绝规则。

访问权限列指示拒绝规则是否拒绝主帐号该权限。如需详细了解拒绝规则,请点击该规则所在行中的查看拒绝规则

允许政策

允许政策部分中,您可以浏览所有相关的允许政策,确定向主帐号授予访问权限的角色绑定,并了解角色绑定授予或不向主帐号授予权限的原因。

Resources 窗格会列出指定的资源及其祖先实体。每个资源旁边都有一个访问权限评估项目。此评估仅适用于该资源的允许政策,不反映来自继承的政策的任何访问权限。如果您无权查看资源的允许政策,则资源列表不包含该资源。

如需查看资源允许政策中的相关角色绑定,并了解它们如何授予或不向主帐号授予权限,请点击该资源。允许政策的绑定显示在 Role bindings 窗格中。

角色绑定窗格包含所选资源的允许政策中角色绑定的表。默认情况下,该表仅包含具有指定权限的角色的角色绑定。如果主账号没有访问权限,则该表还会显示具有可修改自定义角色的角色绑定。如需查看所有角色绑定,请取消选中仅显示相关绑定复选框。

访问权限列指示角色绑定是否向主帐号授予了权限。如需详细了解角色绑定,请点击该绑定所在行中的 See binding details(查看绑定详细信息)。

gcloud

响应包含四个主要部分:请求中访问元组的说明、允许政策评估结果、拒绝政策评估结果,以及整体访问权限状态。

  • accessTuple:请求中访问元组的说明,包括您提供的任何条件上下文。本部分还包含适用于资源的标记的摘要。
  • allowPolicyExplanation:有关相关允许政策是否向主帐号授予权限的摘要,后跟允许政策及其角色绑定的列表。

    对于每项允许政策,响应都会列出政策中的所有角色绑定,并根据以下条件对其进行评估:

    • 绑定是否包含该权限。
    • 绑定是否包含主账号。
    • 是否满足绑定中的条件(如果有)。

    然后,响应会输出允许政策的完整 JSON 文本。

  • denyPolicyExplanation:相关拒绝政策是否拒绝主帐号的权限摘要,后面是包含拒绝政策的资源列表。对于每个资源,响应都会列出附加到该资源的所有拒绝政策。

    对于每项拒绝政策,响应都会输出政策的元数据,列出政策中的拒绝规则,然后根据以下条件评估每条规则:

    • 拒绝规则是否包含该权限。
    • 权限是否在拒绝规则中列为例外情况。
    • 拒绝规则是否包含主帐号。
    • 主账号是否在拒绝规则中列为例外情况。
    • 是否满足拒绝规则中的条件(如果有)。
  • overallAccessState:主帐号是否能够使用指定的权限来访问指定资源(根据相关的允许和拒绝政策)。

    相关的允许和拒绝政策包括:

    • 资源的允许政策
    • 资源的拒绝政策(如果有)
    • 资源的父级项目、文件夹和组织的允许政策(如有)
    • 资源的父级项目、文件夹和组织的拒绝政策(如果有)

    由于政策沿用,父级项目、文件夹和组织的允许和拒绝政策是相关的。将允许或拒绝政策附加到项目、文件夹或组织时,该政策也适用于该项目、文件夹或组织内的所有资源。

    例如,如果组织的拒绝政策指出主账号无法使用特定权限,则主账号无法将该权限用于组织内的任何资源。即使该组织内的文件夹和项目具有更宽松的拒绝政策,或向主帐号授予权限的允许政策,此规则也适用。

    同样,如果项目的允许政策为主账号授予特定权限,则主账号对项目内的任何资源都拥有该权限,前提是他们未被拒绝该权限。

  • 响应中的许多对象也具有 relevance 字段。此字段中的值表示相应对象对整体访问状态的影响程度。relevance 字段可以具有以下值:

    • HEURISTIC_RELEVANCE_HIGH:表示对象对结果有很大影响。换句话说,移除对象可能会更改整体访问权限状态。例如,向主帐号授予指定权限的角色绑定将具有此相关性值。

    • HEURISTIC_RELEVANCE_NORMAL:表示对象对结果的影响有限。换言之,移除对象不太可能改变整体访问状态。例如,不包含该权限的拒绝规则或主账号将具有此相关性值。

REST

响应包含四个主要部分:整体访问权限状态、请求中访问元组的说明、允许政策评估的结果,以及拒绝政策评估的结果。

  • overallAccessState:主帐号是否能够使用指定的权限来访问指定资源(根据相关的允许和拒绝政策)。

    相关的允许和拒绝政策包括:

    • 资源的允许政策
    • 资源的拒绝政策(如果有)
    • 资源的父级项目、文件夹和组织的允许政策(如有)
    • 资源的父级项目、文件夹和组织的拒绝政策(如果有)

    由于政策沿用,父级项目、文件夹和组织的允许和拒绝政策是相关的。将允许或拒绝政策附加到项目、文件夹或组织时,该政策也适用于该项目、文件夹或组织内的所有资源。

    例如,如果组织的拒绝政策指出主账号无法使用特定权限,则主账号无法将该权限用于组织内的任何资源。即使该组织内的文件夹和项目具有更宽松的拒绝政策,或向主帐号授予权限的允许政策,此规则也适用。

    同样,如果项目的允许政策为主账号授予特定权限,则主账号对项目内的任何资源都拥有该权限,前提是他们未被拒绝该权限。

  • accessTuple:请求中访问元组的说明,包括您提供的任何条件上下文。本部分还包含适用于资源的标记的摘要。
  • allowPolicyExplanation:有关相关允许政策是否向主帐号授予权限的摘要,后跟允许政策及其角色绑定的列表。

    对于每项允许政策,响应都会列出政策中的所有角色绑定,并根据以下条件对其进行评估:

    • 绑定是否包含该权限。
    • 绑定是否包含主账号。
    • 是否满足绑定中的条件(如果有)。

    然后,响应会输出允许政策的完整 JSON 文本。

  • denyPolicyExplanation:相关拒绝政策是否拒绝主帐号的权限摘要,后面是包含拒绝政策的资源列表。对于每个资源,响应都会列出附加到该资源的所有拒绝政策。

    对于每项拒绝政策,响应都会输出政策的元数据,列出政策中的拒绝规则,然后根据以下条件评估每条规则:

    • 拒绝规则是否包含该权限。
    • 权限是否在拒绝规则中列为例外情况。
    • 拒绝规则是否包含主帐号。
    • 主账号是否在拒绝规则中列为例外情况。
    • 是否满足拒绝规则中的条件(如果有)。
  • 响应中的许多对象也具有 relevance 字段。此字段中的值表示相应对象对整体访问状态的影响程度。relevance 字段可以具有以下值:

    • HEURISTIC_RELEVANCE_HIGH:表示对象对结果有很大影响。换句话说,移除对象可能会更改整体访问权限状态。例如,向主帐号授予指定权限的角色绑定将具有此相关性值。

    • HEURISTIC_RELEVANCE_NORMAL:表示对象对结果的影响有限。换言之,移除对象不太可能改变整体访问状态。例如,不包含该权限的拒绝规则或主账号将具有此相关性值。

排查条件角色绑定问题

Policy Troubleshooter 会根据标记自动对条件角色绑定和拒绝规则进行问题排查。但是,如需排查其他类型的条件角色绑定或条件拒绝规则问题,Policy Troubleshooter 需要与请求相关的其他上下文。例如,如需根据日期/时间属性对条件进行问题排查,Policy Troubleshooter 需要相应的请求时间。

在 gcloud CLI 和 REST API 中,您需要手动提供这些额外的上下文。

在 Google Cloud 控制台中,您可以直接通过任何管理员活动审核日志数据访问审核日志进行问题排查,以提供额外的背景信息。每个审核日志条目对应于一个 Google Cloud API 请求或 Google Cloud 代表您执行的操作。通过审核日志排查问题时,Policy Troubleshooter 自动获取有关该请求的额外信息(例如其日期和时间),这让 Policy Troubleshooter 能够分析条件角色绑定和拒绝规则。

控制台

如需对条件角色绑定和拒绝规则进行问题排查,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到 Logs Explorer 页面。

    转到日志浏览器

  2. 如果页面标题为旧式日志查看器,请点击升级下拉列表,然后选择升级新的日志浏览器

  3. 如需仅查看管理员活动和数据访问审核日志,请在查询构建器中输入以下查询,然后点击运行查询

    logName=("RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity" OR "RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Fdata_access")
    

    替换以下值:

    • RESOURCE_TYPE:要为其列出审核日志的资源类型。请使用 projectsfoldersorganizations
    • RESOURCE_ID:您的资源的 ID。
  4. 找到对应于您要排查问题的请求的审核日志条目。如需了解如何使用日志浏览器查找特定日志条目,请参阅使用日志浏览器

  5. 在日志条目的摘要列中,点击 IAM,然后点击排查访问权限问题

    Policy Troubleshooter 使用日志条目中的信息来排查访问权限问题,然后显示结果。其他上下文列在条件上下文下的评估详细信息中。如需查看上下文详情,请点击查看条件上下文。如需详细了解 Policy Troubleshooter 结果页面,请参阅本页面上的排查访问权限问题

  6. 可选:如需对涉及条件角色绑定和拒绝规则的其他请求进行问题排查,请返回“日志浏览器”页面并重复上述步骤。

gcloud

如需对条件角色绑定和拒绝规则进行问题排查,请使用 gcloud policy-troubleshoot iam 命令。

在使用下面的命令数据之前,请先进行以下替换:

  • EMAIL:您要排查其权限问题的主账号的电子邮件地址。
  • RESOURCE:授予的权限的资源。
  • PERMISSION:您要进行问题排查的权限。
  • DESTINATION_IP:可选。检查条件角色绑定时使用的请求目标 IP 地址。例如 198.1.1.1
  • DESTINATION_PORT:可选。检查条件角色绑定时使用的请求目标端口。例如,“8080”。
  • REQUEST_TIME:可选。检查条件角色绑定时使用的请求时间戳。使用 RFC 3339 格式的时间戳,例如 2099-02-01T00:00:00Z
  • RESOURCE_NAME:可选。检查条件角色绑定时使用的资源名称值。如需查看接受的资源名称格式列表,请参阅资源名称格式
  • RESOURCE_SERVICE:可选。检查条件角色绑定时使用的资源服务值。如需查看接受的服务名称列表,请参阅资源服务值
  • RESOURCE_TYPE:可选。如需查看接受的资源类型的列表,请参阅资源类型值

执行 gcloud policy-troubleshoot iam 命令:

Linux、macOS 或 Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION --destination-ip=DESTINATION_IP \
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME \
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE \
    --resource-type=RESOURCE_TYPE

Windows (PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION --destination-ip=DESTINATION_IP `
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME `
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE `
    --resource-type=RESOURCE_TYPE

Windows (cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION --destination-ip=DESTINATION_IP ^
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME ^
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE ^
    --resource-type=RESOURCE_TYPE

响应包含主帐号访问权限的说明。对于每个包含条件的角色绑定和拒绝规则,响应都会包含一个 conditionExplanation 字段,用于描述条件根据您提供的条件上下文评估结果是 true 还是 false。

例如,下面是对角色绑定的评估,该绑定包含一个指定资源类型和资源服务的条件:

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "evaluationStates": [{
      "end": 51,
      "start": 1,
      "value": true
    }, {
      "end": 99,
      "start": 55,
      "value": true
    }],
    "value": true,
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
}
...

REST

如需对条件角色绑定和拒绝规则进行问题排查,请使用 Policy Troubleshooter API 的 iam.troubleshoot 方法。

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

  • EMAIL:您要排查其权限问题的主账号的电子邮件地址。
  • RESOURCE:授予的权限的资源。
  • PERMISSION:您要进行问题排查的权限。
  • DESTINATION_IP:可选。检查条件角色绑定时使用的请求目标 IP 地址。例如 198.1.1.1
  • DESTINATION_PORT:可选。检查条件角色绑定时使用的请求目标端口。例如,“8080”。
  • REQUEST_TIME:可选。检查条件角色绑定时使用的请求时间戳。使用 RFC 3339 格式的时间戳,例如 2099-02-01T00:00:00Z
  • RESOURCE_NAME:可选。检查条件角色绑定时使用的资源名称值。如需查看接受的资源名称格式列表,请参阅资源名称格式
  • RESOURCE_SERVICE:可选。检查条件角色绑定时使用的资源服务值。如需查看接受的服务名称列表,请参阅资源服务值
  • RESOURCE_TYPE:可选。如需查看接受的资源类型的列表,请参阅资源类型值

HTTP 方法和网址:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

请求 JSON 正文:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION",
    "conditionContext": {
      "destination": {
        "ip": DESTINATION_IP,
        "port": DESTINATION_PORT
      },
      "request": {
        "receiveTime": REQUEST_TIME
      },
      "resource": {
        "name": RESOURCE_NAME,
        "service": RESOURCE_SERVICE,
        "type": RESOURCE_TYPE
      }
    }
  }
}

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

响应包含主帐号访问权限的说明。对于每个包含条件的角色绑定和拒绝规则,响应都会包含一个 conditionExplanation 字段,用于描述条件根据您提供的条件上下文评估结果是 true 还是 false。

例如,下面是对角色绑定的评估,该绑定包含一个指定资源类型和资源服务的条件:

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "value": true,
    "evaluationStates": [{
      "start": 1,
      "end": 51,
      "value": true
    }, {
      "start": 55,
      "end": 99,
      "value": true
    }]
  }
}
...

后续步骤