IAM Conditions 概览

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

借助 IAM Conditions,您可以选择仅在满足指定条件时向主账号授予访问权限。例如,您可以向用户授予临时访问权限,以便他们解决生产问题,也可以仅向从公司办公室发出请求的员工授予访问权限。

在资源允许政策的角色绑定中指定条件。如果条件存在,则仅当条件表达式的计算结果为 true 时,系统才会向访问请求授权。每个条件表达式都是一组逻辑语句,用于指定要检查的一个或多个特性。

带条件的允许政策

允许政策由一个或多个具有以下结构的角色绑定组成:

"bindings": [
  {
    "role": ...,
    "members": ...,
    "condition": ...
  },
  ...
]

condition 对象是选填项,每个角色绑定可以包含零个或一个条件。如果角色绑定没有 condition 对象,则该角色绑定中的主账号始终拥有资源的指定角色。

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

condition 对象具有以下结构:

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

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

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

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

适用于条件的 CEL

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

在 IAM Conditions 中,CEL 子集主要用来根据特性数据实现布尔值授权决策。通常,条件表达式由一个或多个通过最多 12 个逻辑运算符(&&||!)进行联接的语句组成。每个语句表示一条适用于角色绑定且基于特性的控制规则,并最终确定是否允许访问。

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')

请求特性

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

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

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

在以下示例中,组织定义了一种访问权限级别 CorpNet,以限制对某一 IP 地址范围(网络流量通过这些 IP 地址进入和离开公司网络)的访问。仅当请求满足 CorpNet 访问权限级别时,才允许访问:

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

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

API 特性表达式示例

仅允许用户授予和撤消 Billing Account Administrator (roles/billing.admin) 角色:

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

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

日期/时间表达式示例

在指定的到期日期/时间之前允许临时访问:

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") <= 5

仅允许在指定月份和年份(基于德国柏林时区)进行访问:

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'
  ])
)

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

仅允许访问请求中的某些子网域或网址路径:

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

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

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

如果在特定时间内发出请求,与资源名称前缀匹配,具有所需的访问级别且满足特定资源类型,则允许访问:

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")

后续步骤