了解政策

Google Cloud 资源的访问权限控制受 Cloud IAM 政策管理。Cloud IAM 政策与资源关联,它通过政策沿用限制资源本身及所有子级资源的访问权限。

本主题提供了 Cloud IAM 政策的 JSON 示例,不过也支持 YAML。

政策结构

政策是绑定、审核配置和元数据的统称。绑定指定了应如何授予对资源的访问权限。它将一个或多个成员与单个角色以及任何用于更改角色授予方式和时间的上下文特定条件进行关联(绑定)。AuditConfig 字段指定了有关应如何审核访问尝试的配置数据。元数据包含政策的其他相关信息(例如 ETag版本),便于政策管理。各部分的说明如下:

  • 绑定列表。每个绑定都包含以下字段:
    • 成员也称为身份或主帐号,它可以是用户帐号、服务帐号,Google 群组或网域。
    • 角色是一组命名的权限,可授予对 Google Cloud 资源执行操作的权限。
    • 条件是一种逻辑表达式,可根据请求的属性(例如其来源、目标资源等)进一步限制角色绑定。发出访问请求后,您通常可以根据上下文使用条件来表示各种限制。
  • AuditConfig 字段,用于配置政策的审核日志记录。
  • 元数据,它包括以下字段:
    • etag 字段,用于并发控制并确保以一致的方式更新每个政策。
    • version 字段,用于指定给定政策的架构版本。 有关 version 字段的用法,请详见政策版本部分。

Cloud IAM 政策中的角色绑定是指角色和一系列成员的组合。如果角色绑定还包含条件,则称为条件角色绑定。

在政策中使用 ETag

当多个系统同时尝试写入同一个 Cloud IAM 政策时,这些系统可能会覆盖彼此的更改。出现该风险是因为修改 Cloud IAM 政策涉及三个操作:检索当前政策、根据需要修改其内容,然后完整地设置新政策。如果两个系统同时执行此操作,则其中一个系统可能会设置更新后的政策,而没有发现最初检索的政策此时已发生更改。

为了避免这种情况,Cloud IAM 支持通过在政策中使用 etag 字段来实现并发控制。每次检索政策时,都请务必在提交政策修改版时使用所检索到的政策中的 etag。如果政策在检索后被修改,则 etag 不一致且更新将失败。

出现此情况时,请重新尝试执行整个操作:重新检索政策、应用修改并提交更新后的政策。建议您在用于管理 Cloud IAM 政策的所有代码或脚本中自动执行此重试逻辑。

示例:简单政策

请思考下列示例政策,它将一名成员绑定到一个角色:

{
      "bindings": [
        {
          "members": [
            "user:jim@example.com"
          ],
          "role": "roles/owner"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 1
    }
    

在上例中,jim@example.com 被授予了 Owner 原初角色,但不受任何条件限制。针对原初角色的绑定通常过于宽松;在此情况下,Owner 角色包含的权限超过 1000 个。我们建议您授予预定义角色自定义角色,而不是原初角色,因为这些角色类型的范围和权限数量受到限制。

示例:包含多个绑定的政策

请思考下列示例政策,它包含多个绑定。每个绑定授予的角色各不相同:

{
      "bindings": [
        {
          "members": [
            "user:jim@example.com"
          ],
          "role": "roles/resourcemanager.organizationAdmin"
        },
        {
          "members": [
            "user:alice@example.com",
            "user:jim@example.com"
          ],
          "role": "roles/resourcemanager.projectCreator"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 1
    }
    

上述示例中,Jim (jim@example.com) 在第一个角色绑定中被授予了 Organization Admin 预定义角色 (roles/resourcemanager.organizationAdmin)。此角色包含组织、文件夹和限定项目操作的权限。在第二个角色绑定中,Jim 和 Alice (alice@example.com) 都通过 Project Creator 角色 (roles/resourcemanager.projectCreator) 获得了创建项目的能力。这些绑定合在一起,向 Jim 和 Alice 授予了精确的访问权限,其中向 Alice 授予的访问权限是向 Jim 授予的权限的子集。

示例:采用条件角色绑定的政策

请思考以下 Cloud IAM 政策,它将成员绑定到一个预定义角色,并使用条件表达式限制角色绑定:

{
      "bindings": [
        {
          "members": [
            "group:prod-dev@example.com",
            "serviceAccount:prod-dev-example@appspot.gserviceaccount.com"
          ],
          "role": "roles/appengine.Deployer",
          "condition": {
              "title": "Expires_July_1_2020",
              "description": "Expires on July 1, 2020",
              "expression":
                "request.time < timestamp('2020-07-01T00:00:00.000Z')"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }

在此示例中,policy 字段设置为 3,因为政策包含条件表达式。政策中的绑定是条件角色绑定;它将角色授予 Google 群组 prod-dev@example.com 和服务帐号 prod-dev-example@appspot.gserviceaccount.com,但仅限于 2020 年 7 月 1 日。

有关各政策版本支持的功能的详细信息,请参阅本页上的政策版本

政策限制

Cloud IAM 政策存在以下限制:

  • 在资源层次结构的相应级层支持 Cloud IAM 政策的每项 Google Cloud 资源最多可以有一个政策。例如,组织、文件夹、项目或单个资源(比如 Compute Engine 磁盘、映像等)。
  • 每个 Cloud IAM 政策可以包含多达 1,500 个 members。这些成员中最多有 250 个可以是 Google 群组。

    Cloud IAM 计数每个绑定中的所有成员。它不会重复出现在多个绑定中的成员。例如,如果成员 user:alice@example.com 出现在 50 个绑定中,那么您可以在政策的所有绑定中添加另外 1450 个成员。

  • 一般而言,在调用 setIamPolicy() 或更新 Cloud Console 中的角色绑定后,对政策所作的任何更改都将在 60 秒内生效。但在某些情况下,政策更改可能需要长达 7 分钟才能在整个系统中完全传播。

  • 某些 Google Cloud 服务目前不支持资源级层的条件政策。例如,虽然可对项目设置用于限制服务资源访问权限的条件政策,但尚不支持对资源本身设置条件政策。如需了解详情,请参阅 Cloud IAM Cloud IAM Conditions 特性参考文档

政策沿用和资源层次结构

Google Cloud 资源分层整理,其中组织节点是层次结构中的根节点,其次是文件夹(可选),然后是项目。其他资源大部分是在项目之下创建和管理的。 除层次结构中的根节点外,每项资源只有一个父级。如需了解详情,请参阅资源层次结构主题。

在设置 Cloud IAM 政策时,请务必考虑资源层次结构。在层次结构中的较高级层(例如在组织级层、文件夹级层或项目级层)设置政策时,所授予的访问权限范围包括关联了此政策的资源级层及该级层中的所有资源。例如,在组织级层设置的政策适用于组织和组织中的所有资源。同样,在项目级层设置的政策适用于项目和项目中的所有资源。

政策沿用描述了各政策如何应用于资源层次结构相应级层中的资源。有效政策描述了如何为资源沿用资源层次结构中的所有父级政策。该政策是下列政策的集合:

  • 对资源设置的政策,以及
  • 针对层次结构中资源的所有祖先资源级层设置的政策

每个影响资源有效政策的新角色绑定(沿用自父级资源)都将进行独立评估。如果任何更高级层的角色绑定授予了对请求的访问权限,则会授予针对该资源请求的特定访问权限。

如果任何级层的资源沿用的政策引入了新的角色绑定,则访问权限范围会扩大。

示例:政策沿用

要了解政策沿用,请参考在组织级层设置的下列示例政策:

组织级层政策

{
      "bindings": [
        {
          "members": [
            "user:alice@example.com"
          ],
          "role": "roles/storage.objectViewer"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 1
    }
    

Storage Object Viewer 角色 (roles/storage.objectViewer) 包含对项目和 Cloud Storage 对象的 getlist 权限。在组织级层进行设置时,此角色绑定应用于组织中的各个级层,包括所有项目以及这些项目中的所有 Cloud Storage 对象。

为了进一步说明政策沿用,请查看在 myproject-123 级层进一步设置政策时会出现什么情况:

项目级层的政策

{
      "bindings": [
        {
          "members": [
            "user:alice@example.com"
          ],
          "role": "roles/storage.objectCreator"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 1
    }
    

在上例中,Storage Object Creator 角色 (roles/storage.objectCreator) 在 myproject-123 级层下向 Alice 授予了创建 Cloud Storage 对象的权限。现在有两个角色绑定向 Alice 授予了在 myproject-123 级层访问目标 Cloud Storage 对象的权限。

  • 组织级层的政策授予了在此组织内列出和获取所有 Cloud Storage 对象的权限
  • myproject-123 级层的政策授予了在关联了该政策的 myproject-123 级层创建对象的权限。

下表总结了 Alice 的有效政策:

在组织级层通过“storage.objectViewer”角色获得的权限 在“myproject-123”级层通过“storage.objectCreator”角色获得的权限 Alice 在“myproject-123”级层的有效授权范围
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.create
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
storage.objects.create

政策版本

随着时间的推移,Cloud IAM 可能会增添将在政策架构中大幅添加或更改字段的新功能。为避免破坏依赖于政策结构一致性的现有集成,新的政策架构版本中引入了此类更改。

如果您是首次集成 Cloud IAM,建议使用当前可用的最新架构政策版本。下面我们将探讨不同的可用版本及其各自的用法。此外,还将介绍如何指定所需的版本并引导您完成一些问题排查方案。

现有的所有 Cloud IAM 政策都将 version 字段指定为政策元数据的一部分。请参考下面突出显示的部分:

    {
      "bindings": [
        {
          "members": [
            "user:jim@example.com"
          ],
          "role": "roles/owner"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 1
    }
    

此字段指定了政策的语法架构版本。政策的每个版本都包含可供绑定使用的特定语法架构。新版本可能包含不受早期版本支持的较新语法架构的角色绑定。此字段只能用于政策语法架构控制。

有效的政策版本

Cloud IAM 政策可以使用以下政策版本:

版本 说明
1 用于政策的 Cloud IAM 语法架构的第一个版本。支持将一个角色与一名或多名成员绑定。不支持条件角色绑定。
2 留待内部使用。
3 在角色绑定中引入 condition 字段,该字段通过基于上下文和基于属性的规则限制角色绑定。如需了解详情,请参阅Cloud IAM Conditions 概览

在获取政策时指定政策版本

对于 REST API 和客户端库,当您获取 Cloud IAM 政策时,我们建议您在请求中指定政策版本。当请求指定了政策版本时,Cloud IAM 会假定调用者知道该政策版本中的功能,并能正确处理。

如果请求未指定政策版本,则 Cloud IAM 会假定调用者需要版本 1 政策。

当您获取政策时,Cloud IAM 会检查请求中的政策版本;如果请求未指定版本,则检查默认版本。 Cloud IAM 还会检查政策中是否存在版本 1 政策不支持的字段。它使用此信息来确定要发送的响应类型:

  • 如果政策不包含任何条件,则 Cloud IAM 始终会返回版本 1 政策,而不考虑请求中的版本号。
  • 如果政策包含条件,并且调用者请求版本 3 政策,则 Cloud IAM 会返回包含这些条件的版本 3 政策。 如需查看示例,请参见此页面上的情景 1
  • 如果政策包含条件,并且调用者请求了版本 1 政策或未指定版本,则 Cloud IAM 会返回版本 1 政策。

    对于包含条件的角色绑定,Cloud IAM 会将字符串 _withcond_ 附加到角色名称,后跟哈希值;例如,roles/iam.serviceAccountAdmin_withcond_2b17cc25d2cd9e2c54d8。条件本身不存在。如需查看示例,请参见此页上的情景 2

此行为可防止不知道条件角色绑定的旧客户端库出现问题。如需了解详情,请参阅本页中政策版本的客户端库支持

情景 1:完全支持 Cloud IAM Conditions 的政策版本

假设您调用以下 REST API 方法来获取项目的 Cloud IAM 政策:

POST https://cloudresourcemanager.googleapis.com/v1/projects/[PROJECT-ID]:getIamPolicy
    

请求正文包含以下文本:

{
      "options": {
        "requestedPolicyVersion": 3
      }
    }
    

响应包含项目的 Cloud IAM 政策。如果政策包含至少一个条件角色绑定,则其 version 字段设置为 3

{
      "bindings": [
        {
          "members": [
            "user:user@example.com"
          ],
          "role": "roles/iam.securityReviewer",
          "condition": {
              "title": "Expires_July_1_2020",
              "description": "Expires on July 1, 2020",
              "expression": "request.time < timestamp('2020-07-01T00:00:00.000Z')"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }

如果政策不包含条件角色绑定,即使请求指定的版本为 3,其 version 字段也会设置为 1

{
      "bindings": [
        {
          "members": [
            "user:user@example.com"
          ],
          "role": "roles/iam.securityReviewer",
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 1
    }

情景 2:有限支持 Cloud IAM Conditions 的政策版本

假设您调用以下 REST API 方法来获取项目的 Cloud IAM 政策:

POST https://cloudresourcemanager.googleapis.com/v1/projects/[PROJECT-ID]:getIamPolicy
    

请求正文为空,它不会指定版本号。因此,Cloud IAM 使用默认政策版本 1

该政策包含条件角色绑定。由于政策版本为 1,因此该条件不会出现在响应中。为了表示角色绑定使用了条件,Cloud IAM 会将字符串 _withcond_ 附加到角色名称,后跟哈希值:

{
      "bindings": [
        {
          "members": [
            "user:user@example.com"
          ],
          "role": "roles/iam.securityReviewer_withcond_58e135cabb940ad9346c"
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 1
    }

在设置政策时指定政策版本

当您设置 Cloud IAM 政策时,我们建议在请求中指定政策版本。当请求指定了政策版本时,Cloud IAM 会假定调用者知道该政策版本中的功能,并能正确处理。

如果请求未指定政策版本,则 Cloud IAM 只会允许可以出现在版本 1 政策中的字段。作为最佳做法,请勿更改版本 1 政策中的条件角色绑定;因为该政策不会显示每个条件的绑定,您不知道实际授予绑定的时间和位置。您需要获取政策的版本 3 表示(显示每个绑定的条件),并使用该表示来更新绑定。

情景:请求和响应中的政策版本

假设您使用 REST API 获取 Cloud IAM 政策,并在请求中指定版本 3。响应包含以下政策,该政策使用版本 3

{
      "bindings": [
        {
          "members": [
            "user:alice@example.com"
          ],
          "role": "roles/storage.admin",
          "condition": {
              "title": "Weekday_access",
              "description": "Monday thru Friday access only in America/Chicago",
              "expression": "request.time.getDayOfWeek('America/Chicago') >= 1 && request.time.getDayOfWeek('America/Chicago') <= 5"
          }
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 3
    }

您决定 alice@example.com 整周都应具有 Storage Admin 角色 roles/storage.admin,而不仅仅是在工作日。您可以从角色绑定中移除该条件,然后发送 REST API 请求以设置政策;再一次在请求中指定版本 3

{
      "bindings": [
        {
          "members": [
            "user:alice@example.com"
          ],
          "role": "roles/storage.admin"
        }
      ],
      "etag": "BwUjMhCsNvY=",
      "version": 3
    }
    

响应中包含更新后的政策:

{
      "bindings": [
        {
          "members": [
            "user:alice@example.com"
          ],
          "role": "roles/storage.admin"
        }
      ],
      "etag": "BwWd8I+ZUAQ=",
      "version": 1
    }

响应中的政策使用版本 1,即使请求指定了版本 3,因为该政策仅使用版本 1 政策支持的字段。

政策版本的客户端库支持

Google Cloud 的某些客户端库仅支持版本 1 政策。如果您的客户端库不支持更高版本的政策,则无法使用仅在更高版本中提供的功能。例如,Cloud IAM Conditions 需要支持政策版本 3

如果使用版本 1 政策中不提供的 Cloud IAM 功能,比如 Cloud IAM Conditions,请使用支持该政策版本的客户端库,并在请求中正确设置它。

Cloud IAM 的以下 Google API 客户端库支持政策版本 3

语言 支持政策版本 3 的版本
C# Google.Apis >=v1.41.1
Go google-api-go-client >=v0.10.0
Java
Node.js googleapis >=v43.0.0
PHP google/apiclient >=v2.4.0
Python google-api-python-client >=v1.7.11
Ruby google-api-client >=v0.31.0

您可以使用这些客户端库管理针对以下服务的资源的版本 3 Cloud IAM 政策:

  • Cloud IAM
  • Cloud KMS
  • 云端存储
  • Compute Engine
  • 资源管理器

其他客户端库,包括 Google Cloud 客户端库,仅支持版本 1 政策。

政策版本的 gcloud 支持

如果使用 gcloud 工具管理 Cloud IAM 政策,请确保使用的是 263.0.0 或更高版本。 早期版本仅支持版本 1 政策。

要检查 gcloud 工具的版本号,请运行gcloud version。 要更新到最新版本,请运行 gcloud components update

政策最佳做法

以下最佳做法适用于拥有众多 Google Cloud 用户的组织:

  • 使用相同的访问配置来管理多个用户帐号时,请改用 Google 群组。将每个单独的用户帐号添加到群组中,并向群组而非单个用户帐号授予预期角色。

  • 在组织级层授予的权限:请仔细考虑哪些成员在组织级层获得了访问权限。对于大多数组织而言,只有少数特定团队(例如安全和网络团队)应获得资源层次结构中此级层的访问权限。

  • 在文件夹级层授予的权限:请考虑使用文件夹层级来反映组织的运营结构,其中每个父级/子级文件夹均可使用符合业务和运营需求的不同访问权限集进行配置。例如,父级文件夹可能反映了某个部门,其中的一个子级文件夹可能反映资源访问权限和群组操作,另一个子级文件夹可能反映小团队。这两个文件夹都可能包含满足其团队运营需求的项目。以这种方式使用文件夹可以确保访问权限恰当分离,同时遵循从父级文件夹和组织沿用的政策。在创建和管理 Google Cloud 资源时,这种做法需要的政策维护更少。

  • 在项目级层授予的权限:仅根据特定组或单个精确权限的需要在项目级层授予角色绑定。为了便于管理(特别是在具有多个项目时),强烈建议尽可能在文件夹级层设置政策。

后续步骤