最新消息:在TwitterMastodon上取得專案更新

approver-policy

approver-policy 是一個 cert-manager 核准器,它會根據 CertificateRequestPolicy 自訂資源中定義的政策來批准或拒絕 CertificateRequest。

安裝

請參閱安裝指南,以取得有關如何安裝 approver-policy 的說明。

設定

範例原則資源可以在這裡找到。

當建立 CertificateRequest 時,approver-policy 會評估該請求是否適用於任何現有原則,如果適用,則評估是否應批准或拒絕。

為了使 CertificateRequest 適用於某個原則並因此被其評估,它必須透過 RBAC 進行綁定,並且由原則選擇器選中。CertificateRequestPolicy 目前僅支援 issuerRef 作為選擇器。

如果至少一個原則允許該請求,則該請求將被批准。如果至少一個原則適用於該請求,但沒有任何一個原則允許該請求,則該請求將被拒絕。

被拒絕的 CertificateRequest 會被視為永久失敗。如果它是為 Certificate 資源建立的,則發行將像所有其他永久發行失敗一樣,使用指數退避重試。既未批准也未拒絕的 CertificateRequest(因為未找到符合的原則)將不會被 cert-manager 進一步處理,直到它被批准或拒絕。

CertificateRequestPolicies 是叢集範圍的資源,可以被認為是「原則設定檔」。它們描述了該原則批准的任何請求。原則使用 RBAC 綁定到 Kubernetes 使用者和 ServiceAccount。

以下是一個原則範例,該原則綁定到所有 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)

「允許」區塊定義與請求中相應屬性匹配的屬性。如果請求省略了「允許」的屬性,則該原則允許該請求,但是如果請求包含「允許」區塊中不存在的屬性,則將拒絕該請求。

「允許」的屬性可以標記為 required,如果為 true,則會強制要求該屬性已在請求中定義。只有在也定義了相應欄位時,才能將欄位標記為 requiredrequired 欄位不適用於 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 與 CertificateRequest 進行比對以進行評估。CertificateRequestPolicy 必須選擇(因此匹配)CertificateRequest,才能考慮對請求進行評估。

⚠️ 請注意,使用者仍然必須受RBAC約束,才能考慮針對請求評估該原則。

approver-policy 支援在請求的 issuerRefnamespace 上進行選擇。

必須至少定義 issuerRef namespace 選擇器,即使設定為空 ({})。如果同時定義了兩個選擇器,則它們都必須與 CertificateRequest 匹配,以便該原則評估該請求。

issuerRef

issuerRef CertificateRequestPolicy 選擇器會根據 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

namespace CertificateRequestPolicy 選擇器會根據 CertificateRequest 建立所在的命名空間進行選擇。選擇器可以使用 matchNamesmatchLabels 來定義。

matchNames 接受一個字串列表,這些字串與命名空間的名稱相符。接受萬用字元 "*"。

matchLabels 接受一個鍵值字串列表,這些字串與建立 CertificateRequest 所在的命名空間的標籤相符。有關 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: {}

外掛程式

外掛程式是在編譯時內建於批准者原則中的外部批准者。外掛程式旨在用作現有原則檢查的擴展,當使用者需要現有檢查無法提供的特殊功能時可以使用。

外掛程式定義為 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 的範例實作。

您是否為批准者原則實作了外掛程式?歡迎透過在 cert-manager 網站專案中開啟提取請求,從此頁面新增連結到您的外掛程式。

API 參考

📖 閱讀 批准者原則 API 參考