Policy Troubleshooter 可帮助您了解主账号是否可以访问资源。给定主账号、资源和权限 Policy Troubleshooter 会检查允许政策、拒绝政策 以及影响主账号访问权限的主账号访问边界 (PAB) 政策。 然后,它会根据这些政策告知您主账号是否可以使用 指定的权限来访问相应资源。它还列出了 并说明它们对主账号的访问权限有何影响。
您可以使用 Google Cloud 控制台、Google Cloud CLI 或 REST API 来访问 Policy Troubleshooter。对于基本查询,使用 Google Cloud 控制台通常速度最快。对于更复杂的 请考虑使用 gcloud CLI 或 REST API。
准备工作
-
Enable the Policy Troubleshooter API.
所需权限
如要全面排查主账号的访问权限问题,您需要拥有以下权限。
拥有排查个别主账号访问权限问题的权限
Policy Troubleshooter 分析主账号对资源的访问权限 基于允许政策、拒绝政策、 Principal Access Boundary Policy 以及 您有权查看的角色如果您无权查看 政策,或者如果您无权查看 自定义角色,那么您可能无法判断主账号是否具有访问权限。
拥有排查允许和拒绝政策问题的权限
如需排查允许和拒绝政策问题,您需要对包含要排查问题的资源的组织拥有相应权限。这些 权限可让您查看控制对集群的访问权限的允许和拒绝政策, 资源。
如需获得排查主账号访问权限问题所需的权限,请让管理员向您授予包含您要排查访问权限问题的资源的组织的以下 IAM 角色:
-
安全审核者 (
roles/iam.securityReviewer
) -
排查拒绝政策问题:
Deny Reviewer (
roles/iam.denyReviewer
) -
使用 Google Cloud CLI 进行问题排查:
Service Usage Consumer (
roles/serviceusage.serviceUsageConsumer
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
如果您无权查看某项资源的允许和拒绝政策,
这些允许和拒绝政策的访问结果为 Unknown
。
用于排查 Principal Access Boundary Policy 问题的权限
如需对 Principal Access Boundary Policy 进行问题排查,您需要拥有 该组织的主账号集包含主账号。您识别此组织的方式取决于主账号类型:
- Google 账号和 Google 群组:与包含主体的 Google Workspace 网域关联的组织
- 联合身份(员工身份池或工作负载中的身份) 身份池):包含的身份池的组织 包含主账号
- 服务账号:所属的项目所在的组织, 服务账号已创建
借助这些权限,您可以查看用于控制主账号可以访问哪些资源的主账号访问权限边界政策。
如需获得排查主账号访问权限问题所需的权限,请让管理员向您授予相应组织的以下 IAM 角色:
-
Principal Access Boundary Policy Viewer (
roles/iam.principalAccessBoundaryViewer
) -
排查绑定到项目、文件夹或组织的主账号集的主账号访问权限边界政策的问题:Organization Administrator (
roles/resourcemanager.organizationAdmin
) -
排查绑定到 Google Workspace 网域的主账号访问权限边界政策的问题:IAM Workforce Pool Admin (
roles/iam.workforcePoolAdmin
) -
排查绑定到员工身份池的主账号访问权限边界政策的问题:
Workspace Pool IAM Admin (
roles/iam.workspacePoolAdmin
) -
对绑定到工作负载身份池的主账号访问权限边界政策进行问题排查:IAM Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
如果您无权查看应用于主账号的 Principal Access Boundary Policy,则 Principal Access Boundary Policy 的访问结果为 Unknown
。
排查群组成员访问权限问题的权限
如果您的允许和拒绝政策包含群组,则您需要安装 Google Workspace
Admin API 权限 groups.read
(用于排查单个群组的访问权限问题)
成员。超级用户和群组管理员会自动拥有此权限。如需向非超级用户或群组管理员的用户授予此权限,请创建自定义 Google Workspace 管理员角色,该角色包含 groups.read
权限(位于 Admin API 权限下)并将其授予用户。
如果您没有这些权限,则包含群组或网域的角色绑定和拒绝规则的访问权限结果为未知,除非角色绑定或拒绝规则也明确包含主账号。
拥有排查网域成员访问权限问题的权限
如果您的允许和拒绝政策包含 Google Workspace 账号或 Cloud Identity 网域,您必须是网域管理员,才能排查个别网域成员的访问权限问题。
如果您没有这些权限,则包含群组或网域的角色绑定和拒绝规则的访问权限结果为未知,除非角色绑定或拒绝规则也明确包含主账号。
排查权限问题
如需排查访问权限问题,您需要以下信息:
- 主账号:要检查的电子邮件地址。电子邮件地址必须引用用户或服务账号。不支持其他类型的主账号,包括群组、网域、员工身份和工作负载身份。
- 资源:资源的完整名称。例如,如需检查项目
my-project
,请输入//cloudresourcemanager.googleapis.com/projects/my-project
。对于其他类型的资源,请参阅完整资源名称示例。 权限:要检查的权限。如果您使用 Google Cloud 控制台,它会在您输入时显示建议列表。
如需排查权限问题,权限必须适用于请求中的资源。换言之, 以某种方式访问资源的权限。如果权限不适用于资源,则请求将失败。例如,如果您尝试对 Google Kubernetes Engine 集群的
compute.instances.get
权限进行问题排查,请求会失败,因为compute.instance.get
权限无法用于访问 Google Kubernetes Engine 集群。如需了解权限的完整列表,请参阅权限参考。
控制台
如要排查访问权限问题,请执行以下操作:
在 Google Cloud 控制台中,前往政策问题排查工具页面。
输入您要查看访问权限的主账号的电子邮件地址。
输入要检查的资源的完整资源名称。
如果您不知道完整的资源名称,请执行以下操作之一:
- 如果您要排查项目、文件夹或组织的访问权限问题, 开始输入以查看自动补全选项。
如果您要排查其他资源类型的访问权限问题,请点击 浏览,打开资源搜索对话框,然后搜索 资源:
- 在选择范围框中,选择要搜索的项目、文件夹或组织。
- 在资源类型框中,选择要搜索的资源类型。
- 在搜索资源框中,输入资源名称的一部分。
- 在结果部分,选择要检查的资源。
- 点击选择以选择资源并关闭对话框。
输入要检查的权限。
如果您不知道完整权限名称,请开始输入以查看自动补全功能 选项。
可选:要检查多项资源和权限,请选择添加其他权限对,并重复上一步骤。
点击检查访问权限。
gcloud
如需了解主账号拥有或没有 IAM 权限的原因,请使用 gcloud beta policy-troubleshoot iam
命令。
在使用下面的命令数据之前,请先进行以下替换:
-
VERSION
:可选。要使用的命令版本。如需仅根据允许和拒绝政策排查访问权限问题,请勿指定版本。如需根据允许、拒绝和主账号访问边界政策排查访问权限问题,请使用版本beta
。 EMAIL
:您要排查其权限问题的主账号的电子邮件地址。RESOURCE
:向其授予权限的资源。PERMISSION
:您要排查其问题的权限。
执行 gcloud beta policy-troubleshoot iam 命令:
Linux、macOS 或 Cloud Shell
gcloud VERSION policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \ --permission=PERMISSION
Windows (PowerShell)
gcloud VERSION policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ` --permission=PERMISSION
Windows (cmd.exe)
gcloud VERSION policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^ --permission=PERMISSION
您应该会收到类似如下所示的响应:
响应
{ "accessTuple": { "conditionContext": { "destination": {}, "effectiveTags": [ { "namespacedTagKey": "project-1/tag-key-1", "namespacedTagValue": "project-1/tag-key-1/tag-value-1", "tagKey": "tagKeys/123456789012", "tagKeyParentName": "projects/123456789012", "tagValue": "tagValues/123456789012" }, ], "request": {}, "resource": {} }, "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/project-1", "permission": "bigtable.instances.create", "permissionFqdn": "bigtable.googleapis.com/instances.create", "principal": "service-account-3@project-1.iam.gserviceaccount.com" }, "allowPolicyExplanation": { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "explainedPolicies": [ { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "bindingExplanations": [ { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "condition": { "expression": "resource.type == \"cloudresourcemanager.googleapis.com/Project\"", "title": "Resource-based condition" }, "conditionExplanation": { "evaluationStates": [ { "end": 62, "value": false } ], "value": false }, "memberships": { "serviceAccount:service-account-1@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/bigquery.admin", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" }, { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "condition": { "expression": "resource.matchTag(\"project-1/tag-key-1\", \"tag-value-1\")", "title": "Tag-based condition" }, "conditionExplanation": { "evaluationStates": [ { "end": 73, "value": true } ], "value": true }, "memberships": { "serviceAccount:service-account-2@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/bigquery.admin", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" }, { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "memberships": { "user:user-2@example.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/compute.admin", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" }, { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "memberships": { "user:user-1@example.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "user:user-3@example.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/iam.serviceAccountTokenCreator", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" }, { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "memberships": { "user:user-2@example.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "user:user-1@example.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_HIGH", "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": { "serviceAccount:service-account-3@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "serviceAccount:service-account-4@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/resourcemanager.projectIamAdmin", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" }, { "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED", "combinedMembership": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "memberships": { "serviceAccount:service-account-4@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }, "relevance": "HEURISTIC_RELEVANCE_NORMAL", "role": "roles/resourcemanager.tagViewer", "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED", "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL" } ], "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/project-1", "policy": { "bindings": [ { "condition": { "expression": "resource.type == \"cloudresourcemanager.googleapis.com/Project\"", "title": "Resource-based condition" }, "members": [ "serviceAccount:service-account-1@project-1.iam.gserviceaccount.com" ], "role": "roles/bigquery.admin" }, { "condition": { "expression": "resource.matchTag(\"project-1/tag-key-1\", \"tag-value-1\")", "title": "Tag-based condition" }, "members": [ "serviceAccount:service-account-2@project-1.iam.gserviceaccount.com" ], "role": "roles/bigquery.admin" }, { "members": [ "user:user-2@example.com" ], "role": "roles/compute.admin" }, { "members": [ "user:user-1@example.com", "user:user-3@example.com" ], "role": "roles/iam.serviceAccountTokenCreator" }, { "members": [ "user:user-2@example.com", "user:user-1@example.com" ], "role": "roles/owner" }, { "members": [ "serviceAccount:service-account-3@project-1.iam.gserviceaccount.com", "serviceAccount:service-account-4@project-1.iam.gserviceaccount.com" ], "role": "roles/resourcemanager.projectIamAdmin" }, { "members": [ "serviceAccount:service-account-4@project-1.iam.gserviceaccount.com" ], "role": "roles/resourcemanager.tagViewer" } ], "etag": "BwYY6ttEMEY=", "version": 3 }, "relevance": "HEURISTIC_RELEVANCE_HIGH" }, ], "relevance": "HEURISTIC_RELEVANCE_HIGH" }, "denyPolicyExplanation": { "denyAccessState": "DENY_ACCESS_STATE_NOT_DENIED", "explainedResources": [ { "denyAccessState": "DENY_ACCESS_STATE_NOT_DENIED", "explainedPolicies": [ { "denyAccessState": "DENY_ACCESS_STATE_NOT_DENIED", "policy": { "createTime": "2024-04-09T23:28:24.103203Z", "displayName": "Troubleshooter v3 prober non-tag deny policy", "etag": "MTgyMzk3MDY4OTY4MDE0ODg4OTY=", "kind": "DenyPolicy", "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F546942305807/denypolicies/deny-policy-1", "rules": [ { "denyRule": { "deniedPermissions": [ "bigquery.googleapis.com/datasets.create" ], "deniedPrincipals": [ "principal://iam.googleapis.com/projects/-/serviceAccounts/service-account-1@project-1.iam.gserviceaccount.com" ] } } ], "uid": "fab63b4d-ecfb-5f06-8a6d-602bf1be5062", "updateTime": "2024-05-20T23:29:38.428095Z" }, "relevance": "HEURISTIC_RELEVANCE_HIGH", "ruleExplanations": [ { "combinedDeniedPermission": { "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_HIGH" }, "combinedDeniedPrincipal": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_HIGH" }, "combinedExceptionPermission": { "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "combinedExceptionPrincipal": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "deniedPermissions": { "bigquery.googleapis.com/datasets.create": { "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_HIGH" } }, "deniedPrincipals": { "principal://iam.googleapis.com/projects/-/serviceAccounts/service-account-1@project-1.iam.gserviceaccount.com": { "membership": "MEMBERSHIP_NOT_MATCHED", "relevance": "HEURISTIC_RELEVANCE_HIGH" } }, "denyAccessState": "DENY_ACCESS_STATE_NOT_DENIED", "relevance": "HEURISTIC_RELEVANCE_HIGH" } ] }, ], "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012", "relevance": "HEURISTIC_RELEVANCE_HIGH" } ], "permissionDeniable": true, "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "overallAccessState": "CANNOT_ACCESS", "pabPolicyExplanation": { "explainedBindingsAndPolicies": [ { "bindingAndPolicyAccessState": "PAB_ACCESS_STATE_NOT_ENFORCED", "explainedPolicy": { "explainedRules": [ { "combinedResourceInclusionState": "RESOURCE_INCLUSION_STATE_NOT_INCLUDED", "effect": "ALLOW", "explainedResources": [ { "relevance": "HEURISTIC_RELEVANCE_NORMAL", "resource": "//cloudresourcemanager.googleapis.com/projects/project-2", "resourceInclusionState": "RESOURCE_INCLUSION_STATE_NOT_INCLUDED" } ], "relevance": "HEURISTIC_RELEVANCE_NORMAL", "ruleAccessState": "PAB_ACCESS_STATE_NOT_ALLOWED" } ], "policy": { "createTime": "2024-04-09T17:40:51.627668Z", "details": { "enforcementVersion": "1", "rules": [ { "effect": "ALLOW", "resources": [ "//cloudresourcemanager.googleapis.com/projects/project-2" ] } ] }, "displayName": "Troubleshooter v3 PAB Policy", "etag": "m64s4IgR80eDJDywuVA2DA==", "name": "organizations/123456789012/locations/global/principalAccessBoundaryPolicies/example-pab-policy", "uid": "puid_11875429267422576641", "updateTime": "2024-04-09T17:40:51.627668Z" }, "policyAccessState": "PAB_ACCESS_STATE_NOT_ENFORCED", "policyVersion": { "enforcementState": "PAB_POLICY_ENFORCEMENT_STATE_NOT_ENFORCED", "version": 1 }, "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "explainedPolicyBinding": { "conditionExplanation": { "evaluationStates": [ { "end": 53, "value": true }, { "end": 153, "start": 58, "value": false }, { "end": 248, "start": 157, "value": false } ], "value": false }, "policyBinding": { "condition": { "expression": "principal.type == 'iam.googleapis.com/ServiceAccount' && (principal.subject=='service-account-1@project-1.iam.gserviceaccount.com' || principal.subject=='service-account-2@project-1.iam.gserviceaccount.com')" }, "createTime": "2024-04-09T17:51:13.504418Z", "displayName": "PAB Policy Binding on project-1 project", "etag": "W/\"hz9IKzHsIqvopqDRcVYDxQ==\"", "name": "projects/123456789012/locations/global/policyBindings/example-policy-binding", "policy": "organizations/123456789012/locations/global/principalAccessBoundaryPolicies/example-pab-policy", "policyKind": "PRINCIPAL_ACCESS_BOUNDARY", "policyUid": "puid_11875429267422576641", "target": { "principalSet": "//cloudresourcemanager.googleapis.com/projects/project-1" }, "uid": "buid_1012746966204940289", "updateTime": "2024-05-09T23:08:56.846355Z" }, "policyBindingState": "POLICY_BINDING_STATE_NOT_ENFORCED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" }, "relevance": "HEURISTIC_RELEVANCE_NORMAL" } ], "principalAccessBoundaryAccessState": "PAB_ACCESS_STATE_NOT_ENFORCED", "relevance": "HEURISTIC_RELEVANCE_NORMAL" } }
REST
如需了解主账号拥有或没有 IAM 权限的原因,请使用 Policy Troubleshooter API
iam.troubleshoot
方法。
在使用任何请求数据之前,请先进行以下替换:
-
VERSION
:要用于此请求的 API 版本。如需仅基于允许和拒绝政策排查访问权限问题,请使用v3
。排查基于访问权限的问题 对于允许、拒绝和主账号访问边界政策,请使用v3beta
。 EMAIL
:您要排查其权限问题的主账号的电子邮件地址。RESOURCE
:向其授予权限的资源。PERMISSION
:您要排查其问题的权限。PROJECT_ID
:您要用于发出请求的项目的 ID。 项目 ID 是字母数字字符串,例如my-project
。
HTTP 方法和网址:
POST https://policytroubleshooter.googleapis.com/VERSION/iam:troubleshoot
请求 JSON 正文:
{ "accessTuple": { "principal": "EMAIL", "fullResourceName": "RESOURCE", "permission": "PERMISSION" } }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
了解问题排查工具结果
控制台
结果页面包含以下信息:
评估详情
评估详情部分包含您要排查问题的访问权限的摘要,包括指定的主账号、资源和权限。如果您要排查多个资源权限对的问题,可以使用访问权限评估列表在这些对之间切换。
政策详情
政策详情部分详细介绍了相关允许、拒绝和主账号访问边界政策如何影响主账号的访问权限。
相关 Principal Access Boundary Policy 包括所有 Principal Access Boundary Policy 绑定的 到包含主账号的主账号集。
相关的允许和拒绝政策包括:
- 资源的允许政策
- 资源的拒绝政策(如果有)
- 资源的父级项目、文件夹和资源的允许政策 组织(如果有)
- 资源的父级项目、文件夹和组织的拒绝政策。 如果有
父级项目、文件夹和组织的允许和拒绝政策 具有相关性 因为政策继承。 将允许或拒绝政策附加到项目、文件夹或组织时,该政策也将适用于该项目、文件夹或组织内的所有资源。
例如,如果组织的拒绝政策表明主账号不能 使用特定权限,则主账号无法将该权限用于任何 组织内的资源。即使文件夹和文件夹 该组织中的项目拥有更宽松的拒绝政策,或者 用于授予主账号权限的政策。
同样,如果项目的允许政策为主账号提供了特定的 则主账号对 但前提是他们没有被拒绝该权限。
政策详情部分包含以下部分:
访问权限状态
访问权限状态部分汇总了每种政策类型的结果 (主账号访问边界政策、拒绝政策和允许政策),并说明 整体成效。结果指示主账号能否使用 访问该资源的权限。
为了让用户能够使用权限访问资源,所有政策类型都必须允许访问。有关详情,请参阅政策 评估。
主账号访问边界政策
在主账号访问权限边界政策部分,您可以查看主账号受约束的所有主账号访问权限边界政策,以及将这些政策绑定到主账号的政策绑定。
政策窗格会列出绑定到包含该主账号的主账号集的所有政策。每项政策旁边都有一个图标,指示该政策 政策会影响主账号的访问权限。
Principal Access Boundary Policy 可能会影响主账号在以下国家/地区的访问权限: 方式:
- 主账号可以访问此资源:Principal Access Boundary Policy 适用于主账号,并且其中一条规则包含所查询的资源。
- 主账号不能访问此资源:Principal Access Boundary Policy 适用于主账号,但所查询的资源不在该政策的规则中。
未强制执行: 在以下情况下,系统不会强制执行 Principal Access Boundary Policy:
- IAM 不会在主账号访问边界政策的强制执行版本中强制执行指定的权限。因此, Principal Access Boundary Policy 无法阻止 访问权限。
- 由于政策绑定中的条件,主账号访问边界政策或绑定不适用于主账号。
- 主账号访问边界政策没有规则。
如果未强制执行主账号访问权限边界政策,则该政策无法影响主账号能否访问资源。
如需查看与主账号访问边界政策关联的规则和绑定,请点击相应政策名称。Policies 窗格旁边的窗格会显示 政策的详细信息
如需查看政策中的规则,请点击边界规则标签页。此标签页会显示相关 Principal Access Boundary Policy 规则的表格。
如果主账号访问权限边界规则会影响 Policy Troubleshooter 查询的整体结果,则该规则就是相关规则。因此,相关规则因 Policy Troubleshooter 结果而异。例如,请考虑以下情况:
- Policy Troubleshooter 会指明主账号可以访问相应资源。因此,相关规则是指使主账号有资格访问资源的规则。
- Policy Troubleshooter 会指明主账号无法访问相应资源。不过,根据相关的 Principal Access Boundary Policy, 则主账号有权访问该资源。因此,没有任何规则是相关的,因为主账号无法访问资源的原因不是主账号访问权限边界政策。
- Policy Troubleshooter 显示主账号无法访问 资源。此外,根据相关的主账号访问边界政策,该主账号不符合访问该资源的条件。因此 相关规则使主账号无法访问 资源。
如需查看政策中的所有主账号访问权限边界规则,请取消选中仅显示相关的规则和绑定复选框。
边界规则表中的发现结果列会指示 Principal Access Boundary Policy 包含查询的资源。如需详细了解该规则,请点击查看规则详情。
如需查看该政策的政策绑定,请点击绑定标签页。此标签页会显示一个表格,其中列出了所选主账号访问边界政策的相关政策绑定。
如果政策绑定有效应用了主账号访问边界,则该绑定是相关的 将政策应用于查询的主账号。要将政策绑定应用于 主账号访问边界政策,必须满足以下条件:
- 在政策绑定中设置的主账号必须包含所查询的主账号
- 对于查询的主账号,政策绑定中的所有条件都必须评估为
true
。
如需查看包含查询主账号的主账号集的所有政策绑定(无论查询的主账号是否满足绑定中的条件),请取消选中仅显示相关规则和绑定复选框。
绑定表中的 Findings 列指示绑定是否 对查询的主账号强制执行。查看政策的更多详情 请点击查看绑定详情。
拒绝政策
在拒绝政策部分,您可以查看所有相关的拒绝政策, 确定拒绝主账号访问的拒绝规则,并了解拒绝的原因 规则拒绝或不拒绝主账号授予该权限。
具有拒绝政策的资源窗格列出了所有相关的拒绝政策, 按其挂接到的资源加以整理每个拒绝政策旁边都有一个 访问权限评估。此评估仅适用于该拒绝政策,不会反映继承的政策中的任何访问权限。如果您 无权查看资源的拒绝政策,则资源列表可以 不包含该资源或其拒绝政策。
如需查看这些拒绝政策中的相关拒绝规则,请点击相应拒绝政策。接收者 如需查看资源拒绝政策中的所有拒绝规则,请点击资源。拒绝规则会显示在拒绝规则窗格中。此窗格包含一个表格,其中包含针对您所选资源或拒绝政策查询的主账号或权限的所有拒绝规则。
访问权限列指示拒绝规则是否拒绝 权限。要详细了解拒绝规则,请在以下位置点击查看拒绝规则: 该规则所在的行中
“允许”政策
在允许政策部分,您可以浏览所有相关的允许 确定向主账号授予访问权限的角色绑定 了解角色绑定为何会授予或没有向主账号授予 权限。
资源窗格列出了指定的资源及其祖先实体。每个资源旁边都有一个访问权限评估。此评估仅适用于相应资源的允许政策,不会反映继承的政策中的任何访问权限。如果您无权查看资源的 允许政策,则资源列表不会包含该资源。
如需查看资源允许政策中的相关角色绑定,以及 如何向主账号授予或不授予该权限?请点击 资源。允许政策的角色绑定会显示在角色绑定窗格中。
角色绑定窗格包含一个表,列出了 所选资源的允许政策。默认情况下,该表仅包含 绑定。如果 主账号没有访问权限,该表还显示了 可修改的自定义角色要查看所有角色绑定,请清除仅显示 相关绑定复选框。
访问权限列指示角色绑定是否向主账号提供了 权限。如需详细了解角色绑定,请点击查看绑定 详情。
gcloud
响应包含四个主要部分:请求中的访问元组的说明、允许政策评估结果、拒绝政策评估结果和总体访问状态。
-
accessTuple
:请求中的访问元组的说明,包括您提供的任何条件上下文。此部分还包含适用于资源的标记摘要。 -
allowPolicyExplanation
:关于相关允许情况的摘要 用于向主账号授予该权限的政策,后跟允许列表 政策及其角色绑定对于每项允许政策,响应都会列出该政策中的所有角色绑定,并根据以下条件对其进行评估:
- 角色绑定是否包含相应权限。
- 角色绑定是否包含主账号。
- 角色绑定中的条件(如果有)是否已满足。
然后,响应会输出允许政策的完整 JSON 文本。
-
denyPolicyExplanation
:相关拒绝状态的摘要 政策拒绝主账号授予权限,然后是资源列表 以及拒绝政策对于每项资源,响应会列出所有拒绝政策 附加到资源。对于每个拒绝政策,响应将输出政策的元数据,并列出 政策中的拒绝规则,然后根据以下规则评估每条规则: 条件:
- 拒绝规则是否包含权限。
- 权限是否在拒绝规则中列为例外情况。
- 拒绝规则是否包含主账号。
- 主账号是否在拒绝规则中列为例外情况。
- 是否满足拒绝规则中的条件(如果有)。
-
overallAccessState
:主账号是否能够使用 授予访问指定资源的指定权限 允许政策、拒绝政策和 Principal Access Boundary Policy。相关的主账号访问权限边界政策包括绑定到包含相应主账号的主账号集的所有主账号访问权限边界政策。
相关的允许和拒绝政策包括:
- 资源的允许政策
- 资源的拒绝政策(如果有)
- 资源的父级项目、文件夹和资源的允许政策 组织(如果有)
- 资源的父级项目、文件夹和组织的拒绝政策。 如果有
由于政策继承,父级项目、文件夹和组织的允许和拒绝政策具有相关性。将允许或拒绝政策附加到项目、文件夹或组织后, 该政策也适用于该项目、文件夹或 组织。
例如,如果组织的拒绝政策表明主账号不能 使用特定权限,则主账号无法将该权限用于任何 组织内的资源。即使文件夹和文件夹 该组织中的项目拥有更宽松的拒绝政策,或者 用于授予主账号权限的政策。
同样,如果项目的允许政策向主账号授予特定权限,则主账号对项目中的任何资源都拥有该权限,前提是该主账号未被拒绝该权限。
为了让用户能够使用权限访问资源,所有政策类型都必须允许访问。如需了解详情,请参阅政策评估。
-
pabPolicyExplanation
:对相关主题 Principal Access Boundary Policy 允许主账号访问 接下来是相关的 Principal Access Boundary Policy 绑定,以及 Principal Access Boundary Policy。Principal Access Boundary Policy 可以允许访问、不允许访问,也可以不强制执行。在以下情况下,系统不会强制执行主账号访问边界政策:
- IAM 不会在主账号访问边界政策的强制执行版本中强制执行指定的权限。因此,Principal Access Boundary Policy 无法阻止访问。
- 因为条件 政策绑定中 Principal Access Boundary Policy 或绑定不适用于 主账号。
- 主账号访问边界政策没有规则。
如果未强制执行 Principal Access Boundary Policy,它不会影响 主账号可以访问该资源
响应中还会列出包含主账号的所有政策绑定,以及每个政策绑定中主账号访问权限边界政策的详细信息:
-
对于每个主账号访问边界政策绑定,响应会输出是否针对主账号强制执行政策绑定,然后输出政策绑定的文本。如果主账号集位于
绑定包含查询的主账号,并且如果
对于查询的主账号,政策绑定的求值结果为
true
。 如果未强制执行政策绑定,则该政策无法影响主账号能否访问资源。 -
对于每个 Principal Access Boundary Policy,响应都会输出以下内容:
- 政策是允许访问、不允许访问还是不允许访问 强制执行。
- 政策的强制执行版本。此版本号 确定 IAM 是否 查询的权限的 Principal Access Boundary Policy。如果未强制执行权限,则该政策无法影响主账号能否访问资源。
-
Principal Access Boundary Policy 中的规则,以及每条规则 允许访问。对于每条规则,响应都会指明 规则中会包含所查询的资源
如果满足以下任一条件,规则中就会包含资源:
响应中的许多对象也包含 relevance
字段。此字段中的值表示相应对象对总体访问状态的贡献程度。relevance
字段可以具有以下值:
HEURISTIC_RELEVANCE_HIGH
:表示对象对 结果。也就是说,移除该对象可能会改变整体 访问状态例如,向主账号授予指定权限的角色绑定将具有此相关性值。HEURISTIC_RELEVANCE_NORMAL
:表示对象的影响有限 。换句话说,移除该对象不太可能改变整体访问状态。例如,不包含 或主账号将具有此相关性值。
REST
响应包含四个主要部分:总体访问状态、请求中的访问元组的说明、允许政策评估结果和拒绝政策评估结果。
-
overallAccessState
:主账号是否能够使用 授予访问指定资源的指定权限 允许政策、拒绝政策和 Principal Access Boundary Policy。相关的主账号访问权限边界政策包括绑定到包含相应主账号的主账号集的所有主账号访问权限边界政策。
相关的允许和拒绝政策包括:
- 资源的允许政策
- 资源的拒绝政策(如果有)
- 资源的父级项目、文件夹和资源的允许政策 组织(如果有)
- 资源的父级项目、文件夹和组织(如果有)的拒绝政策
由于政策继承,父级项目、文件夹和组织的允许和拒绝政策具有相关性。将允许或拒绝政策附加到项目、文件夹或组织后, 该政策也适用于该项目、文件夹或 组织。
例如,如果组织的拒绝政策表明主账号不能 使用特定权限,则主账号无法将该权限用于任何 组织内的资源。即使文件夹和文件夹 该组织中的项目拥有更宽松的拒绝政策,或者 用于授予主账号权限的政策。
同样,如果项目的允许政策向主账号授予特定权限,则主账号对项目中的任何资源都拥有该权限,前提是该主账号未被拒绝该权限。
为了让用户能够使用权限访问资源,所有政策类型都必须允许访问。如需了解详情,请参阅政策评估。
-
accessTuple
:请求中的访问元组的说明,包括您提供的任何条件上下文。此部分还包含适用于资源的标记的摘要。 -
allowPolicyExplanation
:关于相关允许情况的摘要 用于向主账号授予该权限的政策,后跟允许列表 政策及其角色绑定对于每项允许政策,响应都会列出该政策中的所有角色绑定,并根据以下条件对其进行评估:
- 角色绑定是否包含相应权限。
- 角色绑定是否包含主账号。
- 角色绑定中的条件(如果有)是否已满足。
然后,响应会输出允许政策的完整 JSON 文本。
-
denyPolicyExplanation
:相关拒绝状态的摘要 政策拒绝主账号授予权限,然后是资源列表 以及拒绝政策对于每项资源,响应会列出所有拒绝政策 附加到资源。对于每个拒绝政策,响应将输出政策的元数据,并列出 政策中的拒绝规则,然后根据以下规则评估每条规则: 条件:
- 拒绝规则是否包含权限。
- 权限是否在拒绝规则中列为例外情况。
- 拒绝规则是否包含主账号。
- 主账号是否在拒绝规则中列为例外情况。
- 是否满足拒绝规则中的条件(如果有)。
-
pabPolicyExplanation
:对相关主题 Principal Access Boundary Policy 允许主账号访问 接下来是相关的 Principal Access Boundary Policy 绑定,以及 Principal Access Boundary Policy。Principal Access Boundary Policy:可以允许访问,但不允许访问; 或不会强制执行。不会强制执行 Principal Access Boundary Policy, 以下情况:
- IAM 不会在 Principal Access Boundary Policy 的强制执行 version。因此, Principal Access Boundary Policy 无法阻止 访问权限。
- 由于政策绑定中的条件,主账号访问边界政策或绑定不适用于主账号。
- Principal Access Boundary Policy 没有任何规则。
如果未强制执行 Principal Access Boundary Policy,它不会影响 主账号可以访问该资源
响应中还会列出包含主账号的所有政策绑定,以及每个政策绑定中主账号访问权限边界政策的详细信息:
-
对于每个主账号访问边界政策绑定,响应会输出是否针对主账号强制执行政策绑定,然后输出政策绑定的文本。如果主账号集位于
绑定包含查询的主账号,并且如果
对于查询的主账号,政策绑定的求值结果为
true
。 如果未强制执行政策绑定,则该政策无法影响主账号能否访问资源。 -
对于每个 Principal Access Boundary Policy,响应都会输出以下内容:
- 政策是允许访问、不允许访问还是不允许访问 强制执行。
- 政策的强制执行版本。此版本号 确定 IAM 是否 查询的权限的 Principal Access Boundary Policy。如果未强制执行权限,则该政策无法影响主账号能否访问资源。
-
Principal Access Boundary Policy 中的规则,以及每条规则 允许访问。对于每条规则,响应都会指明 规则中会包含所查询的资源
如果满足以下任一条件,规则中就会包含资源:
- 资源已列在规则中。仅 Resource Manager 资源(项目、文件夹和组织)可以直接 Principal Access Boundary Policy 列表。
- 规则中列出了资源的某个祖先(即资源层次结构中位于资源上方的项目、文件夹或组织)。
响应中的许多对象也具有 relevance
字段。此字段中的值表示相应对象对总体访问状态的贡献程度。relevance
字段可以具有以下值:
HEURISTIC_RELEVANCE_HIGH
:表示对象对 结果。也就是说,移除该对象可能会改变整体 访问状态例如,向主账号授予指定权限的角色绑定将具有此相关性值。HEURISTIC_RELEVANCE_NORMAL
:表示对象对结果的影响有限。换句话说,移除该对象不太可能改变整体访问状态。例如,不包含相应权限或主体的拒绝规则将具有此相关性值。
排查条件角色绑定问题
政策问题排查工具会根据标记自动排查条件角色绑定和拒绝规则方面的问题。它还 根据条件自动排查主账号访问边界政策绑定问题 基于主账号。
排查其他类型的条件角色绑定的问题,或 有条件的拒绝规则,Policy Troubleshooter 需要额外的 请求的背景信息。例如,根据以下条件对条件进行问题排查: 日期/时间属性,Policy Troubleshooter 需要 请求。
在 gcloud CLI 和 REST API 中,您需要提供这些额外的上下文信息, 。
在 Google Cloud 控制台中,您可以通过以下方法提供这些额外的上下文: 直接在管理员活动审核日志中排查问题或 数据访问审核日志。每个审核日志条目都对应 向 或者 Google Cloud 对您的 。当您通过审核日志进行问题排查时, Policy Troubleshooter 会自动获取更多信息 例如请求日期和时间 Policy Troubleshooter,用于分析条件角色绑定和 拒绝规则
控制台
如需排查条件角色绑定问题和拒绝规则问题,请执行以下操作:
在 Google Cloud 控制台中,转到日志浏览器页面。
如果页面标题为旧式日志查看器,请点击升级下拉列表,然后选择升级新的日志浏览器。
如需仅查看管理员活动和数据访问审核日志,请在查询构建器中输入以下查询,然后点击运行查询:
logName=("RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity" OR "RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Fdata_access")
替换以下值:
RESOURCE_TYPE
:要为其列出审核日志的资源类型。请使用projects
、folders
或organizations
。RESOURCE_ID
:您的资源的 ID。
找到对应于您要排查问题的请求的审核日志条目。如需了解如何使用日志浏览器查找特定日志条目,请参阅使用日志浏览器。
在日志条目的摘要列中,点击 IAM,然后点击排查访问权限问题。
Policy Troubleshooter 会使用日志条目中的信息 来排查访问权限问题,然后向您显示相关结果。额外背景信息 列在评估详情中的条件上下文下。如需查看情境详情,请点击查看条件情境。如需详细了解政策问题排查工具结果页面,请参阅本页面上的了解问题排查工具结果。
可选:如需排查涉及条件角色绑定和拒绝规则的其他请求的问题,请返回日志浏览器页面并重复以上步骤。
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 }] } } ...
后续步骤
- 使用权限参考文档或预定义角色参考文档确定向缺少权限的用户授予哪个角色。
- 了解 Policy Intelligence 工具,这些工具有助于您了解和管理政策,以便主动改进您的安全配置。