使用通用表达式语言

本页面介绍如何将通用表达式语言 (CEL) 与 CA 池上的证书颁发政策、证书模板以及 Identity and Access Management (IAM) 条件搭配使用。

概览

通用表达式语言 (CEL) 是一种非图灵完整开源语言,可实现用于表达式评估的通用语义。Certificate Authority Service 支持 CEL,以针对证书颁发强制执行各种政策控制措施。

有两种 CEL 方言可与 CA Service 搭配使用:

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

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

创建 CA 池或证书模板时,您可以将 CEL 表达式指定为证书身份限制条件的一部分。通过 CEL 表达式,您可以验证主题和主题备用名称 (SAN) 字段。

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

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

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

  • 主题:subject
  • SAN:subject_alt_names

Subject

您可以使用类型为 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

    privateca.googleapis.com/subject 可通过 api.getAttribute('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'

后续步骤