拒绝政策

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

通过 Identity and Access Management (IAM) 拒绝政策,您可以设置关于访问 Google Cloud 资源的安全措施。借助拒绝政策,您可以定义拒绝规则,以防止某些主帐号使用特定的权限(无论主帐号被授予哪些角色)。

本页面简要介绍了拒绝政策和拒绝规则。如需了解如何创建和更新拒绝政策,请参阅拒绝访问资源

拒绝政策的工作原理

拒绝政策由拒绝规则组成。每条拒绝规则指定以下内容:

  • 一组被权限拒绝的主帐号
  • 拒绝主帐号使用的权限或主帐号无法使用的权限
  • 可选:拒绝权限所必须满足的条件

在主帐号被拒绝时,无论它们被授予哪些 IAM 角色,都无法执行需要该权限的任何操作。这是因为 IAM 始终会先检查相关拒绝政策,然后再检查相关允许政策。有关详情,请参阅政策评估

如需指定拒绝政策的应用位置,您可以将其附加到项目、文件夹或组织。将拒绝政策附加到以上某项资源时,政策中的主帐号便无法使用指定的权限来访问该资源或资源的任何后代

每个项目、文件夹和组织最多可以附加 5 个拒绝政策。这可让您为不同类型的拒绝规则创建单独的拒绝政策。例如,您可以将与合规性相关的拒绝规则放入一个政策中,然后在其他拒绝规则中使用另一个政策。每个拒绝政策都独立于所有其他拒绝政策进行评估。

政策评估

当主帐号尝试访问资源时,IAM 会评估所有相关的允许和拒绝政策,以查看主帐号是否有权访问该资源。它会按以下顺序评估政策:

  1. IAM 会检查所有相关的拒绝政策,以查看主帐号的权限是否被拒绝。相关的拒绝政策是附加到资源的拒绝政策,以及任何继承的拒绝政策

    如果这些拒绝政策中有任何政策阻止主帐号使用所需的权限,则 IAM 会阻止他们访问资源。

    如果没有拒绝政策阻止主帐号使用所需的权限,则 IAM 会继续下一步。

  2. IAM 会检查所有相关的允许政策,以查看主帐号是否具有所需权限。相关的允许政策是附加到资源的允许政策,以及任何继承的允许政策

    如果主帐号具有所需的权限,则 IAM 允许它们访问资源。

    如果主帐号没有所需的权限,则 IAM 将阻止它们访问资源。

下图展示了此政策评估流程:

拒绝政策继承

拒绝政策类似于允许政策,通过资源层次结构继承。将拒绝政策附加到项目、文件夹或组织时,该政策也将适用于该项目、文件夹或组织内的所有资源。

例如,如果组织的拒绝政策规定主帐号无法使用特定权限,则主帐号无法对组织中的任何资源使用该权限。即使该组织中的文件夹和项目具有更宽松的拒绝政策,此规则也适用。

同样,如果项目的拒绝政策表示主帐号无法使用特定权限,则主帐号无法将该权限用于该项目中的任何资源。即使父级组织和文件夹具有更宽松的拒绝政策,此规则也适用。

拒绝条件

拒绝条件指定应用拒绝规则所必须满足的条件。如果条件的评估结果为 true 或无法评估,则会应用拒绝规则,并且主帐号无法使用指定的权限。如果条件的评估结果为 false,则不会应用拒绝规则,并且主帐号可以使用指定的权限(如果有)。

拒绝条件与 IAM 条件的结构相同。但是,拒绝条件只能识别资源标记函数

如需了解如何编写条件,请参阅 IAM 条件概览

拒绝政策的结构

拒绝政策是元数据和拒绝规则的集合。拒绝规则会将一组主帐号与一组拒绝主帐号使用或主帐号无法使用的权限相关联。每条规则还可以指定一个条件,用于确定何时拒绝权限。

例如,以下拒绝政策会阻止所有主帐号删除项目,除非主帐号是 project-admins@example.com 的成员或要删除的项目具有值为 test 的标记。

{
  "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F253519172624/denypolicies/limit-project-deletion",
  "uid": "06ccd2eb-d2a5-5dd1-a746-eaf4c6g3f816",
  "kind": "DenyPolicy",
  "displayName": "Only project admins can delete projects.",
  "etag": "MTc1MTkzMjY0MjUyMTExODMxMDQ=",
  "createTime": "2021-09-07T23:15:35.258319Z",
  "updateTime": "2021-09-07T23:15:35.258319Z",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete"
        ],
        "denialCondition": {
          "title":  "Only for non-test projects",
          "expression": "!resource.matchTag('12345678/env', 'test')"
        }
      }
    }
  ]
}

以下各部分介绍了拒绝政策的元数据和拒绝规则中的字段。

元数据

拒绝政策包含以下元数据:

  • name:拒绝政策的名称。此名称的格式为 policies/ATTACHMENT_POINT/denypolicies/POLICY_ID,其中 ATTACHMENT_POINT 是拒绝政策所附加到的项目、文件夹或组织,POLICY_ID 是拒绝政策的字母数字形式的 ID。
  • uid:由 Google 分配给拒绝政策的唯一 ID。
  • kind:政策类型。拒绝政策的 kind 始终为 DenyPolicy
  • displayName:可选。简单易懂的拒绝政策名称。
  • etag:政策版本的标识符。为防止更新发生冲突,etag 值必须与存储在 IAM 中的值匹配。如果 etag 值不匹配,则请求将会失败。
  • createTime:拒绝政策的创建时间。
  • updateTime:拒绝政策的上次更新时间。

拒绝规则

每条拒绝规则都可能包含以下字段:

  • deniedPrincipals:被权限拒绝的主帐号。您可以列出个别主帐号和主帐号集。个别主帐号类型包括用户帐号和服务帐号。主帐号集包括 Google 群组、Cloud Identity 网域和互联网上的所有用户。

    如需查看有效主帐号类型和标识符列表,请参阅 IAM v2beta API 主帐号标识符

  • exceptionPrincipals:可选。根据拒绝规则排除的主帐号。即使这些主帐号列在 deniedPrincipals 中或属于 deniedPrincipals 中列出的某个组,它们也不会被指定的权限拒绝。

    您可以列出个别主帐号和主帐号集。个别主帐号类型包括用户帐号和服务帐号。主帐号集包括 Google 群组和 Cloud Identity 网域。

    如需查看有效主帐号类型和标识符列表,请参阅 IAM v2beta API 主帐号标识符

  • deniedPermissions:指定的主帐号无法使用的权限或者已拒绝其使用的权限。这些权限使用 IAM v2beta 权限格式,这种格式使用完全限定域名 (FQDN) 来标识服务。格式为 SERVICE_FQDN/RESOURCE.ACTION。Google API 使用网域 *.googleapis.com。例如 iam.googleapis.com/roles.delete

  • denialConditions:可选。影响拒绝规则应用时间的逻辑表达式。如果条件的评估结果为 true 或无法评估,则权限会被拒绝。如果条件的评估结果为 false,则权限不会被拒绝。如需了解详情,请参阅本页上的拒绝条件

常见使用场景

以下是您可能想要使用拒绝政策的常见场景,以及您可以在每种场景中创建的拒绝规则示例。 如需了解如何创建和更新拒绝政策,请参阅拒绝访问资源

集中管理员权限

您可以使用拒绝政策以仅限一组特定的主帐号执行某些类型的管理活动。

例如,假设您希望仅限单个中心团队管理贵组织的自定义角色。为此,您需要创建一个拒绝规则,以拒绝所有用户(管理群组中的用户除外)管理自定义角色所需的权限 (custom-role-admins@example.com):

{
  "deniedPrincipals": [
    "principalSet://goog/public:all"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/custom-role-admins@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/roles.create",
    "iam.googleapis.com/roles.delete",
    "iam.googleapis.com/roles.update",
  ]
}

然后,将此拒绝政策附加到您的组织。

现在,只有 custom-role-admins@example.com 群组的成员才能管理自定义角色,即使其他用户具有所需的权限也是如此。

例如,假设 yuri@example.comtal@example.com 都具有 Organization Role Administrator 角色 (roles/iam.organizationRoleAdmin),但是 yuri@example.comcustom-role-admins@example.com 的成员,而 tal@example.com 不是它的成员。使用此拒绝政策时,只有 yuri@example.com 能够创建、删除和更新角色。

创建授权访问例外

您可以使用拒绝政策来拒绝通过继承获得的权限。借助此功能,您可以选择在资源层次结构中的较高级层授予角色,然后根据需要拒绝该角色对个别较低级层资源的权限。

例如,假设您有一个文件夹 Engineering,其中包含多个项目。您希望为群组 eng@example.com 授予 Service Account Key Admin 角色 (roles/iam.serviceAccountKeyAdmin) 的权限,该角色拥有文件夹中几乎所有项目的权限。但是,您不希望该群组能够在文件夹 example-prod 的某个特定项目中创建和删除服务帐号密钥。

您可以创建以下拒绝规则,而不是向每个项目授予 Service Account Key Admin 角色,以下拒绝规则会拒绝将 Service Account Key Admin 角色的创建和删除权限授予 eng@example.com 中的主帐号:

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

然后,将此拒绝规则添加到拒绝政策,并将该政策附加到项目 example-prod

将拒绝政策附加到项目后,您可以为 eng@example.com 授予 Service Account Key Admin 角色,该角色拥有 Engineering 文件夹的访问权限,但不允许群组在 example-prod 中创建或删除服务帐号密钥。

然后,eng@example.com 的成员能够在所有项目(example-prod 除外)中创建和删除服务帐号密钥。例如,如果 izumi@example.comeng@example.com 的成员,则他们可以为 example-devexample-test 中的服务帐号创建和删除密钥,但不能为 example-prod 中的服务帐号创建和删除密钥。

但是,假设您实际上希望一部分 eng@example.com 能够在 example-prod 中创建和删除服务帐号密钥。此部分由群组 eng-prod@example.com 表示。如需允许 eng-prod@example.com 的成员在 example-prod 中创建和删除服务帐号密钥,您可以添加群组作为拒绝规则中的例外主帐号:

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/eng-prod@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

使用修改后的拒绝政策时,eng-prod@example.com 的成员可以在所有项目(包括 example-prod)中创建和删除服务帐号密钥。例如,如果 charlie@example.comeng-prod@example.com 的成员,则他们可以在 example-devexample-testexample-prod 中创建和删除密钥(即使他们也是 eng@example.com 的成员)。

根据标记阻止访问

标记是一种可以关联到组织、文件夹或项目的键值对。您可以使用拒绝政策根据标记拒绝权限,而无需向每个角色授予添加 IAM 条件。

例如,假设您将您的所有项目标记为 devtestprod。您只希望 project-admins@example.com 的成员能够删除标记为 prod 的项目。

如需解决此问题,请创建一条拒绝规则,用于拒绝除 project-admins@example.com 之外的所有人对标记为 prod 的资源的 cloudresourcemanager.googleapis.com/projects.delete 权限:

{
  "displayName": "Only project admins can delete production projects.",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete"
        ],
        "denialCondition": {
          "title":  "Only for prod projects",
          "expression": "resource.matchTag('12345678/env', 'prod')"
        }
      }
    }
  ]
}

然后,将此拒绝规则添加到拒绝政策,并将该政策附加到您的组织。

由于存在此拒绝规则,因此您可以限制主帐号的访问权限,而无需为其角色授予添加条件。您可以改为授予包含 cloudresourcemanager.googleapis.com/projects.delete 权限的主帐号角色,并依靠拒绝规则来防止 project-admins@example.com 以外的主帐号删除任何标记为 prod 的项目。

例如,假设有 bola@example.comkiran@example.com 这两个用户。这两个用户都具有 Project Deleter 角色 (roles/resourcemanager.projectDeleter)。此外,kiran@example.comproject-admins@example.com 的成员。使用此拒绝政策时,bola@example.com 只能删除带有 devtest 标记的项目。kiran@example.com 可以删除所有项目,无论其标记如何。

后续步骤