最新:在TwitterMastodon

approver-policy

approver-policy 是一个 cert-manager approver,它将根据 CertificateRequestPolicy 自定义资源中定义的策略批准或拒绝 CertificateRequests。

安装

有关如何安装 approver-policy 的说明,请参见 安装指南

配置

可以在 此处 找到示例策略资源。

创建 CertificateRequest 时,approver-policy 将评估请求是否适合任何现有策略,如果适合,则评估是否应批准或拒绝该请求。

要使 CertificateRequest 适合策略并因此由策略评估,它必须通过 RBAC 绑定被策略选择器选中。CertificateRequestPolicy 目前仅支持 issuerRef 作为选择器。

如果至少一项策略允许请求,则批准该请求。如果至少一项策略适合该请求,但这些策略中没有一项允许该请求,则拒绝该请求。

被拒绝的 CertificateRequest 被视为永久失败。如果它是在 Certificate 资源上创建的,则发行将通过 指数级回退 与所有其他永久发行失败一样重新尝试。既未批准也未拒绝的 CertificateRequest(因为未找到匹配的策略)不会被 cert-manager 进一步处理,直到它被批准或拒绝。

CertificateRequestPolicies 是集群范围的资源,可以被认为是“策略配置文件”。它们描述了由该策略批准的任何请求。策略使用 RBAC 绑定到 Kubernetes 用户和 ServiceAccounts。

以下是一个策略的示例,该策略绑定到所有 Kubernetes 用户,这些用户只能请求具有以下通用名称的证书:"hello.world"

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: test-policy
spec:
allowed:
commonName:
value: "hello.world"
required: true
selector:
# Select all IssuerRef
issuerRef: {}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cert-manager-policy:hello-world
rules:
- apiGroups: ["policy.cert-manager.io"]
resources: ["certificaterequestpolicies"]
verbs: ["use"]
# Name of the CertificateRequestPolicies to be used.
resourceNames: ["test-policy"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cert-manager-policy:hello-world
roleRef:
# ClusterRole or Role _must_ be bound to a user for the policy to be considered.
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-policy:hello-world
subjects:
# The users who should be bound to the policies defined.
# Note that in the case of users creating Certificate resources, cert-manager
# is the entity that is creating the actual CertificateRequests, and so the
# cert-manager controller's
# Service Account should be bound instead.
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io

行为

CertificateRequestPolicy 被分成 4 部分:allowedcontraintsselectorplugins

允许

Allowed 是定义与请求中对应属性匹配的属性的块。如果请求省略了允许属性,则策略允许该请求,但如果请求包含出现在 allowed 块中的属性,则策略将拒绝该请求。

允许属性可以标记为 required,如果为 true,则将强制要求请求中已定义该属性。只有当相应字段也已定义时,字段才能标记为 required。字段 required 无法用于 isCAusages

在以下 CertificateRequestPolicy 中,如果请求未请求 DNS 名称,则允许请求,如果请求 DNS 名称 "example.com",则允许请求,但如果请求 "bar.example.com",则拒绝请求。

spec:
...
allowed:
dnsNames:
values:
- "example.com"
- "foo.example.com"
...

在以下示例中,如果请求不包含任何通用名称,则拒绝该请求,但允许通用名称以“.com”结尾的请求。

spec:
...
allowed:
commonName:
value: "*.com"
required: true
...

如果省略了允许字段,则该属性对于请求被视为“拒绝所有”。

允许的字符串字段在其值中接受通配符“*”。模式中出现的通配符“*”表示长度为 0 或更长的任何字符串。仅包含“*”的模式将匹配任何内容。包含 "\*foo" 的模式将匹配 "foo" 以及以 "foo" 结尾的任何字符串(例如 "bar-foo")。包含 "\*.foo" 的模式将匹配 "bar-123.foo",但不匹配 "barfoo"

作为列表的允许字段将允许作为该列表子集的请求。这意味着如果 usages 包含 ["server auth", "client auth"],则仅包含 ["server auth"] 的请求将被允许,但 ["server auth", "cert sign"] 不会被允许。

以下是包含 CertificateRequestPolicy 的所有支持的允许字段的示例。

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: my-policy
spec:
allowed:
commonName:
value: "example.com"
dnsNames:
values:
- "example.com"
- "*.example.com"
ipAddresses:
values:
- "1.2.3.4"
- "10.0.1.*"
uris:
values:
- "spiffe://example.org/ns/*/sa/*"
emailAddresses:
values:
- "*@example.com"
required: true
isCA: false
usages:
- "server auth"
- "client auth"
subject:
organizations:
values: ["hello-world"]
countries:
values: ["*"]
organizationalUnits:
values: ["*"]
localities:
values: ["*"]
provinces:
values: ["*"]
streetAddresses:
values: ["*"]
postalCodes:
values: ["*"]
serialNumber:
value: "*"
...

验证

从 approver-policy 0.11.0 开始,现在可以使用 通用表达式语言 (CEL) 定义更高级的允许请求属性验证规则。添加此功能的主要动机是启用允许请求属性值作为请求命名空间的函数。但由于 CEL 是一种小型编程语言,因此验证规则也可以补充或替代 allowed 属性值规范中的基本通配符支持。

请求属性值在 self 变量中对表达式可用。对于多值请求属性,验证将对每个值执行一次。与 self 变量类似,approver-policy 提供了 cr 变量,该变量表示要验证的请求。此变量是对象类型,在撰写本文时,它只有两个字段:namespacename

在以下示例中,我们使用 approver-policy CEL 验证规则来确保使用 X.509 SVID 证书 发行具有标识命名空间(和服务帐户)的 SPIFFE ID(X.509 URI SAN)。

spec:
...
allowed:
uris:
validations:
- rule: self.startsWith('spiffe://trust.domain/ns/' + cr.namespace + '/sa/')
message: only URIs representing the current namespace in the SPIFFE ID are allowed.
...

有关 CEL 验证可用位置的详细信息,请参阅 approver-policy API 参考文档。对于编写 CEL 表达式,CEL 语言定义 可能会有所帮助。

约束

Constraints 是用于限制请求可以具有哪些属性的块。如果未定义约束,则该属性被视为“允许所有”。

以下是包含 CertificateRequestPolicy 的所有支持的约束字段的示例。

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: my-policy
spec:
...
constraints:
minDuration: 1h
maxDuration: 24h
privateKey:
algorithm: RSA
minSize: 2048
maxSize: 4096
...

选择器

Selector 是一个必需字段,用于将 CertificateRequestPolicies 与 CertificateRequests 匹配以进行评估。CertificateRequestPolicy 必须选择(因此必须匹配)CertificateRequest,才能考虑对其进行请求评估。

⚠️ 请注意,用户仍然必须通过 RBAC 绑定才能考虑对请求进行评估。

approver-policy 支持根据请求的 issuerRefnamespace 进行选择。

必须至少定义 issuerRef namespace 选择器,即使将其设置为为空 ({})。如果定义了这两个选择器,则两个选择器都必须与 CertificateRequest 匹配,才能由策略评估请求。

issuerRef

CertificateRequestPolicy 选择器 issuerRef 会选择 CertificateRequest 上对应的 issuerRef 段落。

issuerRef 值接受通配符“*”。如果 issuerRef 设置为空对象 {},则策略将匹配所有请求。

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: my-policy
spec:
...
selector:
issuerRef:
name: "my-ca"
kind: "*Issuer"
group: "cert-manager.io"
apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: match-all-requests
spec:
...
selector:
issuerRef: {}

namespace

The namespace CertificateRequestPolicy 选择器会根据创建 CertificateRequest 的 Namespace 进行选择。选择器可以使用 matchNamesmatchLabels 定义。

matchNames 接受一个字符串列表,用于匹配 Namespace 的名称。支持通配符 "*".

matchLabels 接受一个键值字符串列表,用于匹配创建 CertificateRequest 的 Namespace 的标签。有关 matchLabels 行为的更多信息,请参阅 Kubernetes 文档

如果将 namespace 设置为空对象 {},则策略将与所有请求匹配。

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: my-policy
spec:
...
selector:
namespace:
matchNames:
- "default"
- "app-team-*"
matchLabels:
foo: bar
team: dev
apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: match-all-requests
spec:
...
selector:
namespace: {}

插件

插件是在编译时内置到 approver-policy 中的外部批准者。插件旨在用作现有策略检查的扩展,在用户需要现有检查无法提供的特殊功能的情况下使用。

插件在 CertificateRequestPolicy spec 上定义为一个块。

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
name: plugins
spec:
...
plugins:
my-plugin:
values:
val-1: key-1

社区中已知的插件

如果您想实现外部批准者策略插件,请查看 https://github.com/cert-manager/example-approver-policy-plugin 中的示例实现。

您是否为 approver-policy 实施了插件?请随时通过在 cert-manager 网站项目 中打开拉取请求,将您的插件链接添加到此页面。

API 参考

📖 阅读 approver-policy API 参考