为服务账号配置情境感知访问权限

本指南介绍了如何设置情境感知访问权限,以根据您定义的访问权限级别,帮助保护服务账号对 Google Cloud API 的访问。

限制

以下限制适用于服务账号的情境感知访问权限政策:

  • 如果服务账号将用于工作流执行和 Cloud Scheduler,则不能将基于网络或 IP 地址的属性用于服务账号绑定。

  • 使用 kubectl 连接到专用 GKE 集群以及使用 Auth 代理连接到 Cloud SQL 的连接无法被情境感知访问权限政策阻止。

  • 如果绑定到服务账号的访问权限级别包含不受支持的属性(例如 Device 属性),则系统会拒绝 API 访问。

  • 服务账号不支持范围限定的访问权限级别。

如果您使用 Cloud Build 和 Cloud Run,建议您使用以下内置 VPC 功能:

准备工作

  1. 确保您拥有Google Cloud 组织和至少一个Google Cloud 项目
  2. 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  3. 安装 Google Cloud CLI。

  4. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  5. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  6. 创建或选择 Google Cloud 项目

    选择或创建项目所需的角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要拥有 Project Creator 角色 (roles/resourcemanager.projectCreator),该角色包含 resourcemanager.projects.create 权限。了解如何授予角色
    • 创建 Google Cloud 项目:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替换为您要创建的 Google Cloud 项目的名称。

    • 选择您创建的 Google Cloud 项目:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替换为您的 Google Cloud 项目名称。

  7. 验证是否已为您的 Google Cloud 项目启用结算功能

  8. 安装 Google Cloud CLI。

  9. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  10. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  11. 创建或选择 Google Cloud 项目

    选择或创建项目所需的角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要拥有 Project Creator 角色 (roles/resourcemanager.projectCreator),该角色包含 resourcemanager.projects.create 权限。了解如何授予角色
    • 创建 Google Cloud 项目:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替换为您要创建的 Google Cloud 项目的名称。

    • 选择您创建的 Google Cloud 项目:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替换为您的 Google Cloud 项目名称。

  12. 验证是否已为您的 Google Cloud 项目启用结算功能

  13. 更新 Google Cloud CLI 组件:
    gcloud components update --quiet
  14. 如果您的项目中还没有服务账号,请创建一个服务账号。此服务账号是访问权限政策的目标。

所需的角色

本部分介绍了使用情境感知访问权限所需的 Identity and Access Management (IAM) 角色。

项目级角色

如需获得项目级权限,请让您的管理员为您授予用户账号或服务账号的 Service Account Admin (roles/iam.serviceAccountAdmin) IAM 角色。 如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

此预定义角色包含项目级所需的 the required permissions 权限。

您也可以使用自定义角色或其他预定义角色来获取此权限。

组织级角色

如需获得组织级所需的权限,请让管理员向您的用户账号或服务账号授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

此预定义角色包含组织级所需的 the required permissions 权限。

您也可以使用自定义角色或其他预定义角色来获取此权限。

将访问权限政策绑定到不同的资源层级

您可以将具有相同强制执行模式的访问权限政策绑定到资源层次结构中不同级别的资源。当资源尝试访问时,情境感知访问权限会先使用绑定到该资源的政策,然后再尝试使用绑定到更高级别资源的政策。

例如,您可以将强制执行模式的访问权限政策直接绑定到服务账号,并将另一个强制执行模式的政策绑定到包含该服务账号的项目。当服务账号尝试访问资源时,情境感知访问权限会评估与该服务账号绑定的政策。对于项目中未绑定访问政策的其他服务账号,情境感知访问权限会评估绑定到项目的强制执行模式政策。如果项目级政策和服务账号级政策的强制执行模式均设置为试运行,也是如此。

您可以使用多项访问权限政策来逐步选择性地部署访问权限政策,例如,您可以执行以下操作:

  1. 在项目级层以试运行模式绑定访问权限政策,并通过检查 Cloud Audit Logs 中是否存在访问权限遭拒事件,确保该政策按预期运行。
  2. 仅将强制执行模式下的访问权限政策绑定到特定服务账号。
  3. 在项目级层以强制执行模式绑定访问权限政策,并根据需要将限制性较低的强制执行模式访问权限政策绑定到特定服务账号。

服务账号的访问权限级别属性

本部分列出了服务账号支持的访问权限级别。

服务账号支持以下属性:

  • 基于公共 IP 地址的 IP 子网。
  • 基于专用 IP 地址的 VPC 网络。
  • 地理定位信息,基于公共 IP 地址。

    当服务账号向任何 Google CloudAPI 发出请求时,情境感知访问权限会评估该请求,并将请求的 IP 地址与情境感知访问权限政策中指定的 IP 地址进行比较。如果 IP 地址匹配,则允许进行 API 调用。如果 IP 地址不匹配,则拒绝 API 调用。

  • 包含通用表达式语言 (CEL) 表达式的自定义访问权限级别。表达式的计算结果必须为 true 才能允许访问,为 false 才能拒绝访问。

    以下 CEL 表达式可用于按服务账号限制访问权限。

    如果请求源自一个或多个指定的项目编号,则表达式的计算结果为 true

        expression: "originatesFromProjects(origin, [PROJECT_NUMBER, ...])"
        

    originatesFromProjects 检查请求是否来自与指定项目关联的网络,以及请求是否来自专用 IP 地址。

  • 一天中的时间,以指定时区中请求的时间和日期为准。

    如需了解详情,请参阅配置时间和日期访问条件

创建访问权限级别

本部分介绍如何在组织内创建访问权限级别。 访问权限级别定义了允许访问的条件。

  1. 按照说明创建基本访问权限级别创建自定义访问权限级别

  2. 请注意访问权限政策的全名,其格式为:accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

创建访问权限绑定

将访问权限级别绑定到所选服务账号。这样做会强制执行访问权限级别中定义的条件。您可以将访问权限级别绑定到单个服务账号或项目中的所有服务账号。

将访问权限级别绑定到特定服务账号

本部分介绍了如何将访问权限级别绑定到特定服务账号。

gcloud

使用 gcloud CLI 将访问权限级别绑定到服务账号。

gcloud access-context-manager cloud-bindings create \
    --organization=ORGANIZATION_ID \
    --service-account=SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com \
    --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

替换以下内容:

  • ORGANIZATION_ID:您的 Google Cloud组织 ID
  • SERVICE_ACCOUNT_NAME:目标服务账号的名称,而非电子邮件地址
  • SERVICE_ACCOUNT_PROJECT_ID:包含目标服务账号的项目的 ID
  • POLICY_ID:访问权限政策的 ID
  • ACCESS_LEVEL_NAME:您创建的访问权限级别的名称

    如需使用情境感知访问权限,但不强制执行访问权限级别和禁止访问,您可以以试运行模式绑定访问权限级别

REST API

如需使用 REST API 将访问权限级别绑定到特定服务账号,请运行以下命令:

  1. 创建一个包含以下内容的 request.json 文件:

    {
      "principal": {
        "serviceAccount": "SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    替换以下内容:

    • SERVICE_ACCOUNT_NAME:目标服务账号的名称,而非电子邮件地址

    • SERVICE_ACCOUNT_PROJECT_ID:包含目标服务账号的项目的 ID

    • POLICY_ID:访问权限政策的 ID

    • ACCESS_LEVEL_NAME:您创建的访问权限级别的名称

  2. 运行以下命令:

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @request.json \
      "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    替换以下内容:

    • PROJECT_ID:您用于进行 API 调用的项目的 ID

    • ORGANIZATION_ID:您的 Google Cloud组织 ID。

将访问权限级别绑定到项目中的所有服务账号

本部分介绍如何将访问权限级别绑定到项目中的所有服务账号。

gcloud

如需使用 gcloud CLI 将访问权限级别绑定到项目中的所有服务账号,请运行以下命令:

gcloud access-context-manager cloud-bindings create \
  --organization=ORGANIZATION_ID \
  --service-account-project-number=PROJECT_NUMBER \
  --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

替换以下内容:

  • ORGANIZATION_ID:您的 Google Cloud组织 ID
  • PROJECT_NUMBER:包含您要绑定访问权限的所有服务账号的项目的编号
  • POLICY_ID:访问权限政策的 ID
  • ACCESS_LEVEL_NAME:您创建的访问权限级别的名称。

REST API

如需使用 REST API 将访问权限级别绑定到项目中的所有服务账号,请执行以下操作:

  1. 创建一个包含以下内容的 request.json 文件:

    {
      "principal": {
        "serviceAccountProjectNumber": "PROJECT_NUMBER"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    替换以下内容:

    • PROJECT_NUMBER:包含您要绑定访问权限的所有服务账号的项目的编号
    • POLICY_ID:访问权限政策的 ID
    • ACCESS_LEVEL_NAME:您创建的访问权限级别的名称。
  2. 运行以下命令:

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    替换以下内容:

    • PROJECT_ID:您用于进行 API 调用的项目的 ID
    • ORGANIZATION_ID:您的 Google Cloud组织 ID

如需使用情境感知访问权限,但不强制执行访问权限级别和拒绝访问,您可以以试运行模式绑定访问权限政策

创建绑定操作的 API 响应包含绑定的名称,其中包含唯一的绑定 ID。

使用试运行模式

您可以在试运行模式下绑定访问权限政策。使用试运行模式时,您的服务账号可以继续访问资源,而不会强制执行。不过,如果服务账号尝试的访问行为违反了访问政策,系统会将违规行为记录到 Cloud Audit Logs 中。

在试运行模式下绑定访问权限政策

gcloud

如需在试运行模式下绑定访问权限政策,请将 --level 参数替换为 --dry-run-level,格式如下:

--dry-run-level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

REST API

如需在试运行模式下绑定访问权限政策,请创建包含以下内容的 request.json 文件:

{
"principal": {
  "serviceAccountProjectNumber": "TARGET_PROJECT_NUMBER"
},
"dryRunAccessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
}

替换以下内容:

  • TARGET_PROJECT_NUMBER:目标项目的项目编号
  • POLICY_ID:访问权限政策的 ID
  • ACCESS_LEVEL_NAME:访问权限级别的名称

检查 Cloud Audit Logs

本部分介绍如何检查 Cloud Audit Logs,以查看服务账号在试运行模式下是否被拒绝访问。如需详细了解如何在 Cloud Audit Logs 中搜索试运行模式条目,请参阅查看试运行模式日志

控制台

如需使用 Google Cloud 控制台查看 Cloud Audit Logs 干运行模式下的服务账号访问拒绝情况,请执行以下操作:

在 Google Cloud 控制台中,前往 Logs Explorer 页面:

前往 Logs Explorer

如果您使用搜索栏查找此页面,请选择子标题为 Logging 的结果。

  1. 在 Google Cloud 控制台中,选择您的项目或组织。

  2. 在“日志查询”字段中,输入以下查询:

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    protoPayload.metadata.dryRunEvaluationResult:DENIED
    SEARCH("`SERVICE_ACCOUNT_NAME`")
    
  3. 在时间范围选择器中,从预定义的相对时间(例如过去 30 分钟过去 1 小时过去 24 小时)中进行选择,或者指定自定义范围。

gcloud

如需使用 gcloud CLI 查看 Cloud Audit Logs 试运行模式下的服务账号访问拒绝情况,请执行以下操作:

gcloud logging read \
'protoPayload.serviceName="contextawareaccess.googleapis.com" AND
 protoPayload.metadata.dryRunEvaluationResult:DENIED AND
 SEARCH("`SERVICE_ACCOUNT_NAME`")' \
  --organization=ORGANIZATION_ID

替换以下内容:

  • ORGANIZATION_ID:组织的 ID
  • SERVICE_ACCOUNT_NAME:服务账号的名称

gcloud logging read 命令支持 --freshness 标志,用于查看相对时间范围内的日志记录信息。例如,通过向命令添加 --freshness=3h,您可以查看过去 3 小时内的试运行模式日志条目。

问题排查

本部分介绍如何排查服务账号的情境感知访问权限问题。

常规问题排查

  1. 查看 Cloud Audit Logs。

    使用以下日志查询,并查看日志条目以了解详情。

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    
  2. 查看情境感知访问权限在记录强制执行事件时报告的访问权限级别资源名称。

  3. 确保访问权限级别是组织级资源。

  4. 确保访问权限政策中的访问权限级别基于服务账号支持的属性。

  5. 验证访问权限政策是否绑定到预期的服务账号。

  6. 确保您的用户身份未受到访问政策的访问权限限制。如果用户身份是具有绑定访问权限政策的 Google 群组的成员,则可能会发生这种情况。该政策可能会限制用户访问权限,从而阻止对服务账号的调用流程。

  7. 请与您的安全管理员联系。

访问遭拒

访问遭拒,原因如下:

  • 您以强制执行模式(而非试运行模式)绑定了访问权限政策。

    您可以使用试运行模式,而不是强制执行,以便服务账号可以访问资源并记录强制执行事件,而不会实际拒绝访问资源。此外,您还可以按照常规问题排查说明操作。

  • 需要更新访问权限级别,以纳入更多来源。例如,正在使用的 IP 地址未包含在创建访问权限级别时所用的 IP 地址中。

后续步骤