IAM Conditions 概览

本页面介绍了 Identity and Access Management (Cloud IAM) 的 Conditions 功能。您可以使用 IAM Conditions 为 Google Cloud 资源定义和实施基于特性的条件访问权限控制。

条件和政策类型

您可以在以下位置使用条件:

  • 允许政策
  • 拒绝政策
  • 主账号访问边界政策的政策绑定

以下各部分介绍了如何在这些位置使用条件来强制执行基于属性的访问控制。

允许政策中的条件

您可以使用允许政策中的条件,选择仅在满足指定条件时向主账号授予访问权限。例如,您可以向用户授予临时访问权限,以便他们解决生产问题,也可以仅向从公司网络发出请求的员工授予访问权限。

在资源允许政策的角色绑定中指定条件。如果角色绑定具有条件,则仅当条件表达式的计算结果为 true 时,角色中的主账号才会获得该角色。

如需向角色绑定添加条件,请定义 condition 字段:

"bindings": [
  {
    "role": "ROLE",
    "members": [
      "MEMBER_1",
      "MEMBER_2"
    ],
    "condition": {
      "title": "TITLE",
      "description": "DESCRIPTION",
      "expression": "EXPRESSION"
    }
  }
]

如需详细了解条件中的字段,请参阅本页面上的条件结构

只有部分资源类型接受角色绑定中的条件。但是,您可以通过在组织级层或项目级层授予角色来授予对其他资源类型的有条件访问权限

最佳做法是,向单个允许政策添加的条件角色绑定不要超过 100 个。如果您使用更多数量的条件角色绑定,则可能会超出允许政策的总体大小限制。

如需了解如何添加、修改和移除条件角色绑定,请参阅管理条件角色绑定

拒绝政策中的条件

您可以在拒绝政策中使用条件,以便仅在满足特定条件时应用拒绝规则。例如,只有当主账号尝试访问的资源被标记为 prod 环境的一部分时,您才可以拒绝相应权限。

在资源拒绝政策的拒绝规则中指定条件。如果条件的评估结果为 true 或无法评估,则会应用拒绝规则,并且主账号无法使用指定的权限。如果条件的评估结果为 false,则不会应用拒绝规则,并且主账号可以使用指定的权限(如果有)。

如需向拒绝规则添加条件,请定义 denialCondition 字段:

"rules": [
  {
    "denyRule": {
      "deniedPrincipals": [
        "PRINCIPAL_1",
        "PRINCIPAL_2"
      ],
      "exceptionPrincipals": [
        "EXCEPTION_PRINCIPAL_1",
        "EXCEPTION_PRINCIPAL_2"
      ],
      "deniedPermissions": [
        "DENIED_PERMISSION_1",
        "DENIED_PERMISSION_2"
      ],
      "denialCondition": {
        "title": "TITLE",
        "description": "DESCRIPTION",
        "expression": "EXPRESSION"
      }
    }
  }
]

如需详细了解条件中的字段,请参阅本页面上的条件结构

如需了解如何创建和管理拒绝访问政策,请参阅拒绝访问

Principal Access Boundary Policy 绑定中的条件

您可以使用主账号访问权限边界政策的政策绑定中的条件来细化主账号访问权限边界政策适用的主账号集。例如,您可以仅针对服务账号强制执行政策,或者将 super-admin@example.com 从政策中排除。

在每个政策绑定中指定条件。如果政策绑定具有条件,则仅当条件评估结果为 true 时,政策绑定中的政策才会强制执行。

如需向政策绑定添加条件,请在政策绑定中定义 condition 字段:

{
  "displayName": "DISPLAY_NAME",
  "target": {
    "principalSet": "PRINCIPAL_SET"
  },
  "policyKind": "PRINCIPAL_ACCESS_BOUNDARY",
  "policy": "PAB_POLICY",
  "condition": {
    "title": "TITLE",
    "description": "DESCRIPTION",
    "expression": "EXPRESSION"
  }
}

如需详细了解条件中的字段,请参阅本页面上的条件结构

如需了解如何为主账号访问边界政策创建政策绑定,请参阅将主账号访问边界政策应用于主账号集

条件结构

condition 对象具有以下结构:

"condition": {
    "title": ...,
    "description": ...,
    "expression": ...
}

条件的 title 为必填项,description 为选填项。标题和说明都是纯粹的参考字段,可帮助您识别和描述条件。

expression 是必填字段。该字段使用通用表达式语言 (CEL) 的子集来定义基于特性的逻辑表达式。该条件表达式可以包含多个语句;每个语句评估一个特性。语句使用遵循 CEL 语言规范的逻辑运算符进行组合。

适用于条件的 CEL

通用表达式语言 (CEL) 是 IAM Conditions 中用来指定表达式的表达式语言。它专门用来表达基于特性的逻辑表达式。如需了解详情,请参阅 CEL 规范及其语言定义

在 IAM Conditions 中,CEL 子集主要用来根据特性数据实现布尔值授权决策。通常,条件表达式由一个或多个使用逻辑运算符(&&||!)联接的语句组成。

每个语句表示一条基于属性的控制规则,并最终确定是否适用角色绑定、拒绝规则或政策绑定。

IAM Conditions 中的条件使用以下 CEL 功能:

  • 变量:条件使用“变量”来表示给定特性,例如 request.time(时间戳类型)或 resource.name(字符串类型)。这些变量会根据运行时的上下文填充值。
  • 运算符:每种数据类型(例如时间戳或字符串)都支持一组可用于创建逻辑表达式的“运算符”。通常,运算符用于比较变量中包含的值和字面量值,如 resource.service == 'compute.googleapis.com'。在本示例中,如果 resource.service 的输入值为 compute.googleapis.com,则表达式的计算结果为 true
  • 函数:函数是支持更复杂运算的数据类型的复合运算符。在条件表达式中,有可以与给定数据类型结合使用的预定义函数。例如,request.path.startsWith('/finance') 使用字符串前缀匹配函数,而且如果 request.path 的值包含一个匹配的前缀(如 /finance),则计算结果为 true
  • 逻辑运算符:Conditions 支持三种逻辑运算符(&&||!),您可以将这三种逻辑运算符和基本表达式语句结合使用,构建复杂逻辑表达式。这些逻辑运算符可让您在条件表达式中使用多个输入变量。例如:request.time.getFullYear() < 2020 && resource.service == 'compute.googleapis.com' 连接了两个基本语句,而且必须同时满足这两个语句,才能生成总体计算结果 true

如需详细了解支持的变量、运算符和函数,请参阅特性参考文档

条件特性

条件特性基于所请求的资源(例如其类型或名称)或与请求相关的详细信息(例如其时间戳或者目的地 IP 地址)。

您可以在条件表达式中使用的条件属性取决于您为其编写条件的政策类型。如需查看条件属性的完整列表以及有关每种政策类型支持的属性的更多信息,请参阅属性参考

以下部分展示了您可以在条件中使用的某些属性的示例。

资源特性

您可以使用资源特性来编写用于评估访问请求中的资源的条件。您可以评估的特性如下:

  • 资源类型
  • 资源名称
  • 正在使用的 Google Cloud 服务
  • 附加到资源的标记

如需查看资源特性的完整列表,请参阅资源特性参考文档

如需了解如何使用资源特性来配置基于资源的访问权限,请参阅配置基于资源的访问权限

表达式示例

在角色绑定中,以下条件表达式允许访问 Compute Engine 虚拟机实例,但不允许访问其他类型的资源:

resource.type == 'compute.googleapis.com/Instance'

在角色绑定中,以下条件表达式允许访问 Cloud Storage 资源,但不允许访问其他服务的资源:

resource.service == 'storage.googleapis.com'

在角色绑定中,以下条件表达式仅允许访问特定存储桶中的 Cloud Storage 对象:

resource.type == 'storage.googleapis.com/Object' &&
resource.name.startsWith('projects/_/buckets/exampleco-site-assets/')

在拒绝规则中,以下条件表达式会拒绝访问带有 env: prod 标记的 Google Cloud 资源:

resource.matchTag('123456789012/env', 'prod')

主账号属性

借助主账号属性,您可以根据发出请求的主账号来编写条件。您可以评估的属性如下:

  • 请求中主账号的类型
  • 请求中主账号的身份

如需了解详情,请参阅条件属性参考文档

表达式示例

在主账号访问权限边界政策绑定中,以下条件表达式可确保绑定中的政策仅针对服务账号强制执行:

principal.type == 'iam.googleapis.com/ServiceAccount'

在主账号访问权限边界政策绑定中,以下条件表达式可确保不会对 super-admin@example.com 强制执行绑定中的政策:

principal.subject != 'super-admin@example.com'

请求属性

您可以使用请求特性来编写用于评估请求详情的条件,例如以下条件:

  • 访问权限级别
  • 日期和时间
  • 目的地 IP 地址和端口(适用于 IAP TCP 隧道)
  • 预期网址主机或路径(适用于 IAP)

访问权限级别表达式示例(仅适用于 IAP)

在以下示例中,组织定义了一种访问权限级别 CorpNet,以限制对某一 IP 地址范围(网络流量通过这些 IP 地址进入和离开公司网络)的访问。然后,您可以将以下条件表达式添加到角色绑定中,以便仅在请求满足 CorpNet 访问权限级别时才允许访问:

'accessPolicies/199923665455/accessLevels/CorpNet' in
request.auth.access_levels

您的组织根据请求的特性(例如原始 IP 地址、设备属性、时间等)定义访问权限级别。如需了解详情,请参阅 Access Context Manager 文档

API 属性表达式示例

在具有 iam.projects.setIamPolicy 权限的角色的角色绑定中,以下条件表达式可让用户仅在项目中授予和撤消 Billing Account Administrator (roles/billing.admin) 角色:

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

如需详细了解如何使用 API 特性限制角色授予,请参阅对授予角色设置限制

日期/时间表达式示例

在角色绑定中,以下条件表达式允许访问权限,直至 2021 年 1 月 1 日午夜:

request.time < timestamp('2021-01-01T00:00:00Z')

在角色绑定中,以下条件表达式仅允许在基于德国柏林时区指定的工作时间内进行访问:

request.time.getHours('Europe/Berlin') >= 9 &&
request.time.getHours('Europe/Berlin') <= 17 &&
// Days of the week range from 0 to 6, where 0 == Sunday and 6 == Saturday.
request.time.getDayOfWeek('Europe/Berlin') >= 1 &&
request.time.getDayOfWeek('Europe/Berlin') <= '

在角色绑定中,以下条件表达式仅允许在 2020 年 6 月(基于德国柏林时区)进行访问:

request.time.getFullYear('Europe/Berlin') == 2020
request.time.getMonth('Europe/Berlin') < 6

如需指定时间戳,请使用 RFC 3339 格式。如需指定时区,请使用 IANA 时区数据库中的标识符。

如需详细了解日期/时间表达式,请参阅 CEL 规范

如需了解如何使用日期/时间表达式来配置临时访问权限,请参阅配置临时访问权限

目标 IP 地址和端口表达式示例(适用于 IAP TCP 隧道)

在角色绑定中,以下条件表达式允许访问内部目的地 IP 地址或端口号:

destination.ip == '14.0.0.1'
destination.ip != '127.0.0.1'
destination.port == 22
destination.port > 21 && destination.port <= 23

转发规则表达式示例

在角色绑定中,如果请求没有创建转发规则,或者请求正在为内部 Google Cloud 负载均衡器创建转发规则,则以下条件表达式允许主账号访问:

!compute.isForwardingRuleCreationOperation() || (
  compute.isForwardingRuleCreationOperation() &&
  compute.matchLoadBalancingSchemes([
    'INTERNAL', 'INTERNAL_MANAGED', 'INTERNAL_SELF_MANAGED'
  ])
)

如需详细了解负载均衡方案,请参阅在 Google Cloud 负载均衡器上使用 IAM Conditions

网址主机或路径表达式示例(适用于 IAP)

在角色绑定中,以下条件表达式仅允许访问请求中的某些子网域或网址路径:

request.host == 'hr.example.com'
request.host.endsWith('.example.com')
request.path == '/admin/payroll.js'
request.path.startsWith('/admin')

具有不同类型特性的表达式示例

在角色绑定中,如果在特定时间内发出的请求与资源名称前缀匹配、具有所选访问级别且满足特定资源类型,则以下条件表达式允许访问:

request.time > timestamp('2018-08-03T16:00:00-07:00') &&
request.time < timestamp('2018-08-03T16:05:00-07:00') &&
((resource.name.startsWith('projects/project-123/zones/us-east1-b/instances/dev') ||
 (resource.name.startsWith('projects/project-123/zones/us-east1-b/instances/prod') &&
  'accessPolicies/34569256/accessLevels/CorpNet' in request.auth.access_levels)) ||
 resource.type != 'compute.googleapis.com/Instance')

后续步骤