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

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

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

政策版本和条件角色绑定

允许政策可以用多种不同的形式表示。每种形式都被视为一个允许政策版本

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

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

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

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

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

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

更新 gcloud 工具

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

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

更新客户端库

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

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

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

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

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

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

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

更新 REST API 调用

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

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

更新政策的管理工具

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

  • 所有用于获取或设置允许政策的请求都指定版本 3
  • 所有用于设置允许政策的请求都包含 etag 字段

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

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

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

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

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

    {
      "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. 您可以使用工具检索更新后的允许政策。该工具在请求允许政策时不会指定允许政策版本,因此您会收到包含已修改的角色名称的版本 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

后续步骤