使用通用表达式语言

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

概览

通用表达式语言 (CEL) 是一种开源的非图灵完备语言,用于实现表达式求值的常见语义。Certificate Authority Service 支持 CEL,以强制执行各种政策控制机制来颁发证书。

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

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

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

创建 CA 池或证书模板时,您可以在证书身份限制条件中指定 CEL 表达式。借助 CEL 表达式,您可以验证“Subject”和“Subject Alternative Name (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 条件,请参阅 IAM 条件概览

在对 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 表达式中提供项目编号,则必须在证书请求中也提供项目编号。

表达式示例

确保所有主题的组织设置为“Example”,国家/地区代码设置为 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'

后续步骤