IAM Conditions 概览

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

借助 IAM Conditions,您可以选择仅在满足配置条件时向身份(成员)授予资源访问权限。举例来说,您可以在出现生产问题时为用户配置临时访问权限,或仅为提出请求的公司办公室员工授予访问资源的权限。

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

带条件的 IAM 政策

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

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

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

condition 对象具有以下结构:

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

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

expression 是必填字段。该字段使用通用表达式语言 (CEL) 的子集来定义基于特性的逻辑表达式。下文详细介绍了 CEL。条件 expression 包含多个语句,每个语句使用一个特性,各语句又按照 CEL 语言规范使用逻辑运算符进行组合。

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

适用于条件的 CEL

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

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

下面介绍了与条件有关的最重要的 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 地址,目标 Compute Engine 虚拟机 (VM) 实例的目的地 IP 地址)。下面提供了使用这些特性的表达式示例。

资源特性

通过资源特性,您可以创建条件来评估访问请求中的资源,包括资源类型、资源名称以及所用的 Google Cloud 服务。

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

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

表达式示例

允许访问 Compute Engine 虚拟机实例,但不允许访问其他类型的资源:

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

允许访问 Cloud Storage 资源,但不允许访问其他服务的资源:

resource.service == "storage.googleapis.com"

仅允许访问名称以指定前缀字符串开头的资源:

resource.name.startsWith("projects/_/buckets/exampleco-site-assets-")

请求特性

通过“请求特性”,您可以创建条件来评估请求的详细信息,例如其日期/时间、预期的网址主机/路径(适用于 IAP)、目的地 IP 地址和端口(适用于 IAP TCP 隧道)或访问权限级别。

日期/时间表达式示例

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

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 规范

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

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

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

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

目的地 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

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

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

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

访问权限级别由您的组织定义。访问权限级别是基于请求的特性(例如原始 IP 地址、设备特性、时间等)进行分配。如需详细了解访问权限级别,请参阅 Access Context Manager 文档

转发规则表达式示例

如果请求没有创建转发规则,或者请求正在为内部 Google Cloud 负载平衡器创建转发规则,则允许成员访问:

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

如需详细了解负载平衡方案,请参阅在 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")

接受条件角色绑定的资源

您可以将条件添加到以下类型的 Google Cloud 资源的 IAM 政策:

Google Cloud 服务 资源类型
Cloud Storage 存储分区1
Compute Engine
  • 全局后端服务
  • 地区后端服务
  • 防火墙
  • 映像
  • 实例模板
  • 实例
  • 地区永久性磁盘
  • 区域永久性磁盘
  • 快照
Identity-Aware Proxy (IAP)
  • 隧道
  • 隧道实例
  • 隧道区域
  • 所有 Web 服务
  • 个别 Web 服务
  • Web 服务类型
  • Web 服务版本
Cloud Key Management Service (Cloud KMS)
  • 加密密钥
  • 加密密钥版本
  • 密钥环
Resource Manager
  • 组织
  • 项目
1.您可以在条件中使用 resource.name 特性来引用 Cloud Storage 存储分区中的对象。但是,您必须将条件添加到更高级别的资源(例如存储分区或项目)的 IAM 政策。

其他类型的资源不允许在其 IAM 政策中使用条件。但是,您可以在组织级层或项目级层添加条件角色绑定,其他资源将通过资源层次结构继承这些角色绑定。

如需详细了解哪些特性会影响哪些资源类型,请参阅特性参考文档

已知限制

IAM Conditions 存在以下限制:

  • 如本页面中支持的服务的相关详细信息所述,您只能为所选 Google Cloud 服务向角色绑定添加条件。此外,大多数条件特性都只与有限数量的服务兼容。
  • 原初角色roles/ownerroles/editorroles/viewer)不受支持;如果您尝试在使用原初角色的角色绑定中设置条件,则 setIamPolicy 操作将失败。
  • allUsersallAuthenticatedUsers 值不是条件角色绑定支持的成员类型。如果您指定其中一种成员类型,则 setIamPolicy 操作将失败。
  • 我们建议每个政策包含的条件角色绑定不超过 100 个。一个政策存在着底层存储空间大小限制。包含多个条件角色绑定的政策可能会超出大小限制,因此可能会被拒绝。
  • 我们建议您为同一角色的同一成员仅设置几个不同的条件角色绑定(不同条件)。不过,您最多可以为同一角色和同一成员添加 20 个角色绑定。如果超过此数目,则 setIamPolicy 操作将失败。
  • 一个条件表达式中最多可以使用 12 个逻辑运算符。如果超过此数目,则 setIamPolicy 操作将失败。

后续步骤