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

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

限制

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

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

  • 使用 kubectl 连接到专用 GKE 集群以及使用 Auth Proxy 连接到 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 地址。
  • VPC 网络,基于专用 IP 地址。
  • 地理位置,基于公共 IP 地址。

    当服务帐号向 Google Cloud API 发出任何请求时,情境感知访问权限会评估该请求,并将请求的 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:Access Context Manager 访问权限政策的 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:Access Context Manager 访问权限政策的 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:Access Context Manager 访问权限政策的 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:Access Context Manager 访问权限政策的 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:Access Context Manager 访问权限政策的 ID
  • ACCESS_LEVEL_NAME:访问权限级别的名称

检查 Cloud Audit Logs

本部分介绍了如何检查 Cloud Audit Logs 中服务帐号的试运行模式访问遭拒情况。如需详细了解如何在 Cloud Audit Logs 中搜索 试运行模式条目,请参阅查看试运行模式日志

控制台

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

在 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 地址在创建访问权限级别时未包含在其中。

后续步骤