设置授予角色的限制

在大型组织中,让团队独立管理资源的 Identity and Access Management (IAM) 政策会大有帮助。但是,允许成员授予或撤消所有 IAM 角色会加大安全风险。

您可以设置 IAM Conditions 和 iam.googleapis.com/modifiedGrantsByRole API 属性,允许成员授予和撤消角色。通过这些限制,您可以创建受限的 IAM 管理员,让他们管理自己团队的 IAM 政策,但只能在您设置的边界内进行管理。

准备工作

所需权限

要为成员授予或撤消的角色设置限制,您需要包含以下权限的角色:

  • resourcemanager.resource-type.getIamPolicy
  • resourcemanager.resource-type.setIamPolicy

resource-type 替换为以下项之一:

  • 如果要为组织创建受限的 IAM 管理员,请使用 organizations
  • 如果要为文件夹创建受限的 IAM 管理员,请使用 folders
  • 如果要为项目创建受限的 IAM 管理员,请使用 projects

如需获得这些权限,同时遵循最小权限原则,请让管理员向您授予 Security 管理员角色 (roles/iam.securityAdmin)。

或者,管理员也可以向您授予具有所需权限的其他角色,例如自定义角色或更宽松的预定义角色

常见用例

以下部分介绍如何利用有限的角色授权来启用自助服务管理。

创建受限的 IAM 管理员

设想一个场景,您希望允许用户 Fnn (finn@example.com) 充当项目的受限 IAM 管理员。您希望 Finn 只能授予和撤消项目的 Billing Account Administrator (roles/billing.admin) 和 Billing Account User (roles/billing.user) 角色。

若要授予这些受限的功能,您需要有条件地向 Finn 授予 Project IAM 管理员角色 (roles/resourcemanager.projectIamAdmin)。 Project Administrator Admin 角色允许 Finn 授予和撤消 IAM 角色,以及 Finn 可以授予和撤消哪些角色限制:

{
  "version": 3,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "members": [
        "user:owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "finn@example.com"
      ],
      "role": "roles/resourcemanager.projectIamAdmin",
      "condition": {
        "title": "only_billing_roles",
        "description": "Only allows changes to role bindings for billing accounts",
        "expression":
          "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/billing.admin', 'roles/billing.user'])"
      }
    }
  ]
}

此条件角色绑定允许 Finn 执行以下操作:

  • 授予项目 Billing Account Administrator 和 Billing Account User 角色。
  • 撤消项目 Billing Account Administrator 和 Billing Account User 角色。
  • 为授予 Billing Account Administrator 和 Billing Account User 角色的项目级层角色绑定添加、移除或修改条件。
  • 执行 Project IAM Admin 角色所允许,但不会修改项目 IAM 政策的其他操作。例如,Finn 可以使用 projects.getIamPolicy 方法来获取项目的政策。

此条件角色绑定不允许 Finn 执行以下任一操作:

  • 修改项目以外资源的 IAM 政策。
  • 授予 Billing Account Administrator 或 Billing Account User 角色以外的角色。
  • 撤消 Billing Account Administrator 或 Billing Account User 角色以外的角色。
  • 为不授予 Billing Account Administrator 或 Billing Account User 角色的角色绑定添加、移除或修改条件。

允许用户管理受限的 IAM 管理员

设想一个场景,您希望用户 Lila 为其团队中受限 IAM 管理员。您希望 Lila 只能授予和撤消她负责项目的 Compute Admin 角色 (roles/compute.admin)。但是,您还需要让 Lala 选择其他用户充当受限 IAM 管理员。换句话说,您希望允许 Lila 允许其他用户仅授予和撤消 Compute Admin 角色。

您可能认为此解决方案是授予 Lila 的 Project IAM Admin 角色 (roles/resourcemanager.projectIamAdmin),然后授予她为其他人授予或撤消该角色的权限。但是,如果您授予 Lila Project Project Admin 角色,她可以从自己的角色中移除此条件,并授予其授予或撤消任何 IAM 角色的权限。

为防止此权限升级,您需要为项目的受限 IAM 管理员创建 Google 群组 iam-compute-admins@example.com。然后,将 Lila 添加到群组中,然后让她成为群组管理员

创建群组后,有条件地为该群组授予 Project IAM Admin 角色 (roles/resourcemanager.projectIamAdmin)。Project IAM Admin 角色允许群组成员授予和撤消 IAM 角色,以及限制角色可以授予和撤消的角色:

{
  "version": 3,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "members": [
        "user:owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "iam-compute-admins@example.com"
      ],
      "role": "roles/resourcemanager.projectIamAdmin",
      "condition": {
        "title": "only_compute_admin_role",
        "description": "Only allows changes to role bindings for the Compute Admin role",
        "expression":
          "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/compute.admin'])"
      }
    }
  ]
}

作为 iam-compute-admins@example.com 群组的成员,Lila 可以执行以下操作:

  • 通过为角色添加新绑定或将成员添加到现有角色的现有绑定,为项目授予 Compute Admin 角色。
  • 通过撤消该角色的现有绑定或从现有角色绑定中移除成员来撤消 Compute Admin 角色。
  • 通过为角色的绑定添加、移除或修改条件来修改 Compute Admin 角色的授予。
  • 执行 Project IAM Admin 角色所允许,但不会修改项目 IAM 政策的其他操作。例如,Finn 可以使用 projects.getIamPolicy 方法来获取项目的政策。

作为 iam-compute-admins@example.com 群组的管理员,Lila 通过向 iam-compute-admins@example.com 群组添加 Compute Admin 角色来允许其他用户授予或撤消 Compute Admin 角色。

Lila 无法执行以下操作:

  • 能够授予或撤消其他角色。
  • 修改项目以外资源的 IAM 政策。
  • 授予除 Compute Admin 角色以外的角色。
  • 撤消除 Compute Admin 角色以外的角色。
  • 为不授予 Compute Admin 角色的角色绑定添加、移除或修改条件。

限制角色授予的权限

以下部分介绍了如何让成员仅授予或撤消特定角色。

编写条件表达式以限制角色授予

要限制成员授予角色的能力,请编写条件表达式,指定成员可以授予或撤消的角色。

为条件表达式使用以下格式:

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(roles)

此表达式会执行以下操作:

  • 使用 api.getAttribute() 函数获取 API 属性 iam.googleapis.com/modifiedGrantsByRole

    对于设置资源的 IAM 政策的请求,此特性包含请求修改的角色绑定中的角色名称。对于其他类型的请求,该特性未定义。 在这些情况下,此函数返回默认值 ([])。

  • 使用 hasOnly() 通用表达式语言 (CEL) 函数定义并实施允许成员撤消或撤消的角色。

    hasOnly() 函数的输入是允许成员授予或撤消的角色的列表。如果此列表中包含 iam.googleapis.com/modifiedGrantsByRole 特性中的角色,则该函数返回 true。如果它们不相等,则函数会返回 false

    如果 iam.googleapis.com/modifiedGrantsByRole 属性包含默认值 ([]),则该函数返回 true,因为 [] 不包含列表中未包含的任何角色。

要自定义此表达式,请将 roles 替换为成员允许授予或撤消的角色列表。例如,要仅允许成员授予或撤消 Pub/Sub Editor(roles/pubsub.editor )和 Pub/Sub Publisher (roles/pubsub.publisher ) 角色,请使用值 ['roles/pubsub.editor', 'roles/pubsub.publisher']

允许的角色列表中最多可包含 10 个值。所有这些值必须是字符串常量。

使用条件角色绑定限制角色授予

要允许成员仅授予或撤消某些角色,请使用上一部分中的条件表达式来创建条件角色绑定。然后,向资源的 IAM 政策添加条件角色绑定。

  1. 选择用于表示允许成员为其授予和撤消角色的角色范围的资源:

    • 如果您希望成员授予和撤消组织中所有资源的特定角色,请选择组织。
    • 如果要允许成员授予和撤消文件夹中所有资源的特定角色,请选择一个文件夹。
    • 如果您希望成员授予和撤消项目中所有资源的特定角色,请选择项目。
  2. 选择一个角色,以允许成员为您选择的资源类型(项目、文件夹或组织)设置 IAM 政策。为了遵循最小权限原则,请选择以下预定义角色之一:

    • 项目:Project IAM 管理员 (roles/resourcemanager.projectIamAdmin)
    • 文件夹:Folder IAM 管理员 (roles/resourcemanager.folderIamAdmin)
    • 组织:组织管理员 (roles/resourcemanager.organizationAdmin)。

    或者,选择包含 resourcemanager.resource-type.setIamPolicyresourcemanager.resource-type.getIamPolicy 权限的自定义角色,其中 resource-typeprojectfolderorganization

  3. 有条件地向成员授予您所选的项目、文件夹或组织中的角色。

    系统会应用新政策,并且您的成员只能修改您允许的角色的绑定。

    控制台

    1. 在 Cloud Console 中,转到 IAM 页面。

      转到 IAM 页面

    2. 确保您的项目、文件夹或组织的名称显示在页面顶部的资源选择器中。资源选择器会显示您当前正在处理的项目、文件夹或组织。

      如果您没有看到资源名称,请点击资源选择器,然后选择您的资源。

    3. 在成员列表中,找到将授予和撤消角色的成员,然后点击 按钮。

    4. 修改权限面板中,选择您之前选择的角色。然后在条件下,点击添加条件

    5. 修改条件面板中,输入条件的标题和选填性说明。

    6. 点击条件编辑器标签页,并输入您在编写条件表达式以限制角色授权时编写的表达式。此表达式用于限制成员可以授予或撤消哪些角色。

      例如,以下条件表达式将限制授予和撤消 Pub/Sub Editor (roles/pubsub.editor) 和 Pub/Sub Publisher (roles/pubsub.publisher) 角色的成员:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])
      

      警告:请勿在允许的角色列表中包含以下类型的角色:

      • 有权授予和撤消 IAM 角色的角色(即具有以 setIamPolicy 结尾的权限名称的角色)。
      • 受限 IAM 管理员可修改的自定义角色。例如,如果受限 IAM 管理员还具有角色管理员角色 (roles/iam.roleAdmin )不允许他们授予或撤消项目级层自定义角色。

      可以授予和撤消此类角色的受限 IAM 管理员可以自行授予和撤消所有 IAM 角色。如需了解详情,请参阅编写条件表达式以限制角色授权

    7. 点击保存以应用条件。

    8. 关闭修改条件面板后,点击修改权限面板中的保存以更新 IAM 政策。

    gcloud

    IAM 政策是使用读取-修改-写入模式设置的。

    受限,读取资源的 IAM 政策:

    执行 get-iam-policy 命令。 此命令获取资源的当前 IAM 政策。

    命令:

    gcloud resource-type get-iam-policy resource-id --format=json > path
    

    替换以下值:

    • resource-type:您要允许成员授予或撤消角色的资源类型。请使用以下选项之一:projectsresource-manager foldersorganizations
    • resource-id:您的 Google Cloud 项目、文件夹或组织 ID。
    • path:要下载 IAM 政策的目标文件的路径。

    IAM 政策以 JSON 格式保存,例如:

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

    接下来,修改政策。

    如需让成员仅针对特定角色修改绑定,请添加突出显示的条件角色绑定:

    {
      "bindings": [
        {
          "members": [
            "user:owner@example.com"
          ],
          "role": "roles/owner"
        },
        {
          "members": [
            "member"
          ],
          "role": "role",
          "condition": {
            "title": "title",
            "description": "description",
            "expression":
              "expression"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }

    替换以下值:

    • member:允许或撤消某些角色的成员。例如 user:my-user@example.com。如需查看每个成员类型的格式,请参阅 Binding 参考
    • role:您在上述步骤中选择的角色。此角色必须包含所选资源类型的 setIamPolicy 权限。
    • title:简要描述条件的字符串。例如 only_pubsub_roles
    • description:可选。条件的其他说明。例如 Only allows granting/revoking the Pub/Sub editor and publisher roles
    • expression:您在编写条件表达式以限制角色授权时编写的表达式。此表达式用于限制成员可以授予或撤消哪些角色。

      例如,以下条件表达式将限制授予和撤消 Pub/Sub Editor (roles/pubsub.editor) 和 Pub/Sub Publisher (roles/pubsub.publisher) 角色的成员:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])
      

      警告:请勿在允许的角色列表中包含以下类型的角色:

      • 有权授予和撤消 IAM 角色的角色(即具有以 setIamPolicy 结尾的权限名称的角色)。
      • 受限 IAM 管理员可修改的自定义角色。例如,如果受限 IAM 管理员还具有角色管理员角色 (roles/iam.roleAdmin )不允许他们授予或撤消项目级层自定义角色。

      可以授予和撤消此类角色的受限 IAM 管理员可以自行授予和撤消所有 IAM 角色。如需了解详情,请参阅编写条件表达式以限制角色授权

    最后,写入更新后的政策

    通过为资源执行 set-iam-policy 命令来设置新政策:

    gcloud resource-type set-iam-policy resource-id path
    

    替换以下值:

    • resource-type:您要允许成员授予或撤消角色的资源类型。请使用以下选项之一:projectsresource-manager foldersorganizations
    • resource-id:您的 Google Cloud 项目、文件夹或组织 ID。
    • path:包含更新后的政策文件的路径。

    系统会应用新政策,成员将只能修改您允许的角色。

    REST

    IAM 政策是使用读取-修改-写入模式设置的。

    受限,读取资源的 IAM 政策:

    Resource Manager API 的 getIamPolicy 方法可获取项目、文件夹或组织的 IAM 政策。

    在使用下面的请求数据之前,请先进行以下替换:

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud 项目、组织或文件夹 ID。 项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY_VERSION:要返回的政策版本。请求应指定最新的政策版本,即政策版本 3。如需了解详情,请参阅在获取政策时指定政策版本

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy

    请求 JSON 正文:

    {
      "options": {
        "requestedPolicyVersion": POLICY_VERSION
      }
    }
    

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

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

    接下来,修改政策。

    添加条件角色绑定,使成员只能授予和撤消某些角色。请务必将 version 字段更改为值 3

    {
      "version": 3,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "members": [
            "user:owner@example.com"
          ],
          "role": "roles/owner"
        },
        {
          "members": [
            "MEMBER"
          ],
          "role": "ROLE",
          "condition": {
            "title": "TITLE",
            "description": "DESCRIPTION",
            "expression":
              "EXPRESSION"
          }
        }
      ]
    }
    • MEMBER:允许或撤消某些角色的成员。例如 user:my-user@example.com。如需查看每个成员类型的格式,请参阅 Binding 参考
    • ROLE:您在上述步骤中选择的角色。此角色必须包含所选资源类型的 setIamPolicy 权限。
    • TITLE:简要描述条件的字符串。例如 only_pubsub_roles
    • DESCRIPTION:可选。条件的其他说明。例如 Only allows granting/revoking the Pub/Sub editor and publisher roles
    • EXPRESSION:您在编写条件表达式以限制角色授权时编写的表达式。此表达式用于限制成员可以授予或撤消哪些角色。

      例如,以下条件表达式将限制授予和撤消 Pub/Sub Editor (roles/pubsub.editor) 和 Pub/Sub Publisher (roles/pubsub.publisher) 角色的成员:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])
      

      警告:请勿在允许的角色列表中包含以下类型的角色:

      • 有权授予和撤消 IAM 角色的角色(即具有以 setIamPolicy 结尾的权限名称的角色)。
      • 受限 IAM 管理员可修改的自定义角色。例如,如果受限 IAM 管理员还具有角色管理员角色 (roles/iam.roleAdmin )不允许他们授予或撤消项目级层自定义角色。

      可以授予和撤消此类角色的受限 IAM 管理员可以自行授予和撤消所有 IAM 角色。如需了解详情,请参阅编写条件表达式以限制角色授权

    最后,写入更新后的政策

    Resource Manager API 的 setIamPolicy 方法会将请求中的政策设置为项目、文件夹或组织的新 IAM 政策。

    在使用下面的请求数据之前,请先进行以下替换:

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud 项目、组织或文件夹 ID。 项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY:您要设置的政策的 JSON 格式。如需详细了解政策的格式,请参阅政策参考文档

      例如,要设置上一步中显示的政策,请将 POLICY 替换为以下内容:

      {
        "version": 3,
        "etag": "BwWKmjvelug=",
        "bindings": [
          {
            "members": [
              "user:owner@example.com"
            ],
            "role": "roles/owner"
          },
          {
            "members": [
              "member"
            ],
            "role": "role",
            "condition": {
              "title": "title",
              "description": "description",
              "expression":
                "expression"
            }
          }
        ]
      }
      

    HTTP 方法和网址:

    POST https://iam.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy

    请求 JSON 正文:

    {
      "policy": POLICY
    }
    

    如需发送您的请求,请展开以下选项之一:

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

后续步骤