排查政策和角色绑定中的“withcond”

当您查看 Identity and Access Management (IAM) 政策时,您可能会看到包含字符串 withcond、后跟哈希值的角色名称。例如,您可能会看到像 roles/iam.serviceAccountAdmin_withcond_2b17cc25d2cd9e2c54d8 这样的角色名称。

本页面介绍了在 IAM 政策中何时以及为何会看到字符串 withcond。此外,还会建议您在看到此字符串时应执行的操作。

政策版本和条件角色绑定

IAM 政策可以用多种不同的形式表示。每种形式都称为政策版本

在使用版本 1 的 IAM 政策中,某些角色绑定可能在角色名称中包含字符串 withcond、后跟哈希值:

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

这种格式表示角色绑定是条件绑定。换句话说,只有在满足特定条件的情况下才会授予角色。

版本 1 政策不会显示这些条件。如果您看到字符串 withcond 和哈希值,则角色绑定包含您看不到的条件。

解决方案:指定政策版本 3

为了确保您可以查看和更新整个 IAM 政策(包括其条件),您必须始终在请求中指定政策版本 3。如需指定政策版本 3,请完成以下部分中的任务。

更新 gcloud 工具

如果使用 gcloud 命令行工具,请运行 gcloud version 以检查其版本号。输出中包含类似于 Google Cloud SDK 279.0.0 的字符串。

如果版本号小于 263.0.0,请运行 gcloud components update 以更新 gcloud 工具。在 263.0.0 和更高版本中,gcloud 工具会自动指定支持条件的政策版本。

更新客户端库

如果您的应用使用客户端库,请按照下列步骤执行操作:

  1. 找到客户端库的名称和版本号,然后检查支持政策版本的客户端库列表。

    • 如果您已经使用最新版本的客户端库,并且它支持政策版本,则无需更新客户端库。继续执行下一步。

    • 如果使用的是旧版本客户端库,并且有更高版本支持政策版本,请将您的客户端库更新到最新版本。

    • 如果使用的客户端库不支持政策版本,则可以向应用中添加另一个支持政策版本的客户端库。使用该客户端库来处理 IAM 政策。或者,您也可以直接使用 IAM REST API

  2. 更新您的应用中用于获取和设置 IAM 政策的所有代码:

    • 在您获取政策时,请务必在请求中指定版本 3
    • 在您设置政策时,请务必将政策的 version 字段设置为 3,并在请求中包含 etag 字段

更新 REST API 调用

如果您的应用直接使用 IAM REST API,请更新用于获取和设置 IAM 政策的所有代码:

  • 在您获取政策时,请务必在请求中指定版本 3
  • 在您设置政策时,请务必将政策的 version 字段设置为 3,并在请求中包含 etag 字段

更新 IAM 政策的管理工具

如果您保留 IAM 政策的本地副本(比方说,如果您将它们存储在版本控制系统中,并作为代码进行处理),请确保您使用的所有工具都符合以下条件:

  • 所有请求都指定政策版本 3
  • 所有更新政策的请求都包含 etag 字段

如果某个工具不符合这些条件,请检查该工具的更新版本。

此外,请确保您的管理工具保留条件角色授予,而不是添加不包含条件的重复角色授予。例如,设想以下场景:

  1. 将 Create Service Accounts 角色 (roles/iam.serviceAccountCreator) 授予文件夹 my-folder 上的用户 vikram@example.com。该文件夹的 IAM 政策类似于以下示例:

    {
      "bindings": [
        {
          "members": [
            "user:vikram@example.com"
          ],
          "role": "roles/iam.serviceAccountCreator"
        }
      ],
      "etag": "BuFmmMhCsNY=",
      "version": 1
    }
  2. 您可以使用工具检索 IAM 政策并将其存储在版本控制系统中。

  3. 添加条件,以便 vikram@example.com 只能在正常工作周(根据德国柏林的日期和时间)内创建服务帐号。更新后的 IAM 政策类似于以下示例:

    {
      "bindings": [
        {
          "members": [
            "user:vikram@example.com"
          ],
          "role": "roles/iam.serviceAccountCreator",
          "condition": {
            "title": "work_week_only",
            "expression": "request.time.getDayOfWeek('Europe/Berlin') >= 1 && request.time.getDayOfWeek('Europe/Berlin') <= 5"
          }
        }
      ],
      "etag": "BwWcR/B3tNk=",
      "version": 3
    }
  4. 您可以使用工具检索更新后的 IAM 政策。工具在请求政策时未指定政策版本,因此您会收到角色名称已修改的版本 1 政策:

    {
      "bindings": [
        {
          "members": [
            "user:vikram@example.com"
          ],
          "role": "roles/iam.serviceAccountCreator_withcond_a75dc089e6fa084bd379"
        }
      ],
      "etag": "BwWcR/B3tNk=",
      "version": 1
    }

此时,管理工具可能会确定从 vikram@example.com 到角色 roles/iam.serviceAccountCreator 的绑定已消失,而且应该恢复原始角色与政策的绑定:

避免:无条件的额外角色绑定

{
  "bindings": [
    {
      "members": [
        "user:vikram@example.com"
      ],
      "role": "roles/iam.serviceAccountCreator_withcond_a75dc089e6fa084bd379"
    },
    {
      "members": [
        "user:vikram@example.com"
      ],
      "role": "roles/iam.serviceAccountCreator"
    }
  ],
  "etag": "BwWd3HjhKxE=",
  "version": 1
}

此更改不正确。无论是星期几,它都会将角色 roles/iam.serviceAccountCreator 授予 vikram@example.com。因此,第一个角色绑定中的条件不起作用。

如果您的管理工具尝试进行此类更改,请勿批准更改。而是您必须更新管理工具,才能在请求中指定政策版本 3

后续步骤