使用通用表达式语言

本页面介绍了如何在 CA 池中使用通用表达式语言 (CEL) 与证书颁发政策、证书模板和 Identity and Access Management (IAM) 条件。

概览

通用表达式语言 (CEL) 是一种非图文尔图完整模型的开源语言,可实现表达式计算的通用语义。证书授权机构服务支持 CEL,以强制执行各种政策控制,以便颁发证书。

可以与 CA 服务搭配使用的 CEL 方言有两种:

  • 可在 CA 池的证书颁发政策和证书模板中使用的灵活方言。
  • 可在 IAM 条件中使用的更受限的方言。

证书颁发政策和证书模板的 CEL 方言

创建 CA 池或证书模板时,您可以在证书身份限制条件中指定 CEL 表达式。借助 CEL 表达式,您可以验证主题和主题备用名称 (SAN) 字段。

如需详细了解颁发政策,请参阅将证书颁发政策添加到 CA 池

如需详细了解证书模板,请参阅 证书模板和颁发政策概览

CA 池和证书模板的身份限制条件的 CEL 方言公开了以下变量,用于访问和验证主题和 SAN 字段:

  • 主题:subject
  • SAN:subject_alt_names

主题

您可以使用类型为 Subject 且名称为 subject 的变量验证证书主题域名(包括常用名)中的所有字段,如证书请求中所指定。

Subject 是一个包含以下字段的结构:

类型 名称
String common_name
String country_code
String 组织
String organizational_unit
String 市行政区
String 省/自治区/直辖市
String street_address
String postal_code

主题备用名称 (SAN)

您可以使用 subject_alt_names 变量验证证书请求中指定的所有 SAN。subject_alt_names 变量包含一个 SAN 结构体列表,其中每个 SAN 的类型为 SubjectAltName

SubjectAltName 是一个包含以下字段的结构体:

类型 名称
String
[]Int32 oid
Enum 类型

您可以为 SubjectAltName 类型使用以下值:

  • DNS
  • URI
  • EMAIL
  • IP_ADDRESS
  • CUSTOM

subject_alt_names 变量包含包含所有请求的 SAN 的列表。

您可以在 SAN 中使用以下宏:

  • subject_alt_names.all(san, predicate)
  • subject_alt_names.exists(san, predicate)
  • subject_alt_names.exists_one(san, predicate)
  • subject_alt_names.filter(san, predicate)

如需详细了解宏,请参阅语言定义:宏

表达式示例

确保使用特定的通用名称和一组国家/地区

subject.common_name == "google.com" && (subject.country_code == "US" || subject.country_code == "IR")

确保所有 DNS 名称都以自定义字符串结尾

subject_alt_names.all(san, san.type == DNS && san.value.endsWith(".test.com"))

确保所有 SAN 都是 DNS 或 EMAIL 类型

subject_alt_names.all(san, san.type == DNS || san.type == EMAIL )

确保只有一个具有特定 OID 的自定义 SAN

subject_alt_names.size() == 1 && subject_alt_names[0].oid == [1, 2, 3, 5, 17]

确保自定义 SAN 只是一组 OID

subject_alt_names.all(san, san.oid == [1, 2, 4, 5, 55] || san.oid == [1, 2, 4, 5, 54])

IAM 政策的 CEL 方言

使用 IAM 条件将 IAM 角色绑定应用于条件表达式。如果条件的计算结果为 true,则 IAM 角色绑定有效,否则会被忽略。借助 CA Service,您可以向 CA 池添加 IAM 条件绑定。

IAM 条件是一个 CEL 表达式,它引用有关请求的一组上下文属性,并且计算结果为布尔值。用户可以在 IAM 政策中对角色绑定设置条件,该政策会由 IAM 存储并进行评估,以查看是否允许即将执行的操作。

如需详细了解 IAM Conditions,请参阅 IAM Conditions 概览

在对 IAM 条件进行 CEL 评估期间,系统会公开以下属性:

  • privateca.googleapis.com/subject

    可以通过 api.getAttribute('privateca.googleapis.com/subject', {}) 访问 privateca.googleapis.com/subject

类型 说明
map{string, string} 此字段包含传入证书请求中指定的主题标识名(包括公用名)。

示例

{
 'common_name': 'Foobar',
 'organization': 'Example LLC'
 'country_code' :'US'
 'organizational_unit':'Foobar'
 'locality':'Mountain View'
 'Province':'California'
 'street_address':'Foobar 22'
 'postal_code':55555
}
  • privateca.googleapis.com/subject_alt_names

    privateca.googleapis.com/subject_alt_names 可作为 api.getAttribute('privateca.googleapis.com/subject_alt_names', []) 访问。

类型 说明
list{string} 此字段包含传入证书请求中指定的所有请求的 SAN。每个请求的 SAN 都有其类型前缀。类型未知的 SAN 带有该类型的序列化 OID 前缀。

示例

{
 'dns:foo.bar.com',
 'uri:spiffe://foo/ns/bar/sa/baz'
 'email:foo@bar.com'
 'ip:169.169.254.254'
 'custom:1.2.3.4.5.6.3:foobar'
}
  • privateca.googleapis.com/template

    privateca.googleapis.com/template 可作为 api.getAttribute('privateca.googleapis.com/template', '') 访问。

类型 说明
String 使用的证书模板(如果有)。格式为 {project_id}/-/{template_id}

示例my-project-pki/-/workload_tls

IAM 条件中提供的模板名称必须与证书请求中的模板名称一致。因此,如果您在 CEL 表达式的 privateca.googleapis.com/template 属性中提供项目 ID,则在请求证书时也必须提供项目 ID。如果您提供 项目编号,则必须在 CEL 表达式中提供项目编号 也会显示证书请求

表达式示例

确保所有正文的组织均设置为“示例”国家/地区代码设置为 USUK

api.getAttribute('privateca.googleapis.com/subject', {})['organization'] == 'Example' &&
api.getAttribute('privateca.googleapis.com/subject', {})['country_code'] in ['US', 'UK']

确保证书请求仅包含给定的 DNS SAN

api.getAttribute('privateca.googleapis.com/subject_alt_names', [])
        .hasOnly(['dns:sample1.prod.example.com', 'dns:sample2.prod.example.com'])

确保所有证书都使用特定模板

api.getAttribute('privateca.googleapis.com/template', '') == 'my-project-pki/-/leaf-server-tls'

后续步骤