IAM Conditions 概览

本页面介绍了 Identity and Access Management (Cloud IAM) 的 Conditions 功能。您可以使用 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 语言规范的逻辑运算符进行组合。

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

适用于条件的 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 地址或者目标 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/Bucket" &&
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")

接受条件角色绑定的资源类型

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

Google Cloud 服务 资源类型
Cloud Bigtable (Bigtable)
  • 实例
Cloud Key Management Service (Cloud KMS)
  • 加密密钥
  • 加密密钥版本
  • 密钥环
Cloud SQL 实例
Cloud Storage 存储分区 1、2
Compute Engine
  • 全局后端服务
  • 地区后端服务
  • 防火墙
  • 映像
  • 实例模板
  • 实例
  • 地区永久性磁盘
  • 区域永久性磁盘
  • 快照
Identity-Aware Proxy (IAP)
  • 隧道
  • 隧道实例
  • 隧道区域
  • 所有 Web 服务
  • 个别 Web 服务
  • Web 服务类型
  • Web 服务版本
Resource Manager
  • 单位
  • 文件夹
  • 项目
  • 标记键
  • 标记值
Secret Manager
  • 密文
  • 密文版本

1 适用于使用统一存储分区级访问权限的存储分区。如果您无法启用统一存储分区级访问权限,则可以向更高级别资源(例如项目)的 IAM 政策添加条件。

2 您可以使用 resource.name 特性来引用 Cloud Storage 存储分区中的对象。但是,您必须将条件添加到更高级别的资源(例如存储分区或项目)的 IAM 政策。

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

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

后续步骤