approver-policy
approver-policy は、cert-manager の 承認者であり、CertificateRequestPolicy
カスタムリソースで定義されたポリシーに基づいて CertificateRequest を承認または拒否します。
インストール
approver-policyのインストール方法については、インストールガイドをご覧ください。
設定
ポリシーリソースの例はこちらにあります。
CertificateRequest が作成されると、approver-policy は、リクエストが既存のポリシーに適しているかどうかを評価し、適している場合は、承認または拒否すべきかどうかを評価します。
CertificateRequest がポリシーに適しており、ポリシーによって評価されるためには、RBAC を介してバインドされており、かつ、ポリシーセレクターによって選択されている必要があります。CertificateRequestPolicy は現在、セレクターとして issuerRef
のみをサポートしています。
少なくとも 1 つのポリシーがリクエストを許可する場合、リクエストは承認されます。少なくとも 1 つのポリシーがリクエストに適しているものの、そのいずれもリクエストを許可しない場合、リクエストは拒否されます。
拒否された CertificateRequest は、永続的に失敗したとみなされます。それが Certificate リソースのために作成された場合、発行は他のすべての永続的な発行失敗と同様に、指数バックオフで再試行されます。承認も拒否もされていない(一致するポリシーが見つからなかったため)CertificateRequest は、承認または拒否されるまで、cert-manager によってさらに処理されることはありません。
CertificateRequestPolicy はクラスター スコープのリソースであり、「ポリシー プロファイル」と考えることができます。それらは、そのポリシーによって承認されるすべてのリクエストを記述します。ポリシーは、RBAC を使用して Kubernetes ユーザーおよび ServiceAccount にバインドされます。
以下は、コモンネームが "hello.world"
の証明書のみをリクエストできるすべての Kubernetes ユーザーにバインドされているポリシーの例です。
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: test-policyspec:allowed:commonName:value: "hello.world"required: trueselector:# Select all IssuerRefissuerRef: {}---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:name: cert-manager-policy:hello-worldrules:- apiGroups: ["policy.cert-manager.io"]resources: ["certificaterequestpolicies"]verbs: ["use"]# Name of the CertificateRequestPolicies to be used.resourceNames: ["test-policy"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: cert-manager-policy:hello-worldroleRef:# ClusterRole or Role _must_ be bound to a user for the policy to be considered.apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cert-manager-policy:hello-worldsubjects:# 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: Groupname: system:authenticatedapiGroup: rbac.authorization.k8s.io
挙動
CertificateRequestPolicy は 4 つの部分に分かれています。allowed
、contraints
、selector
、および plugins
です。
許可
許可とは、リクエスト内の対応する属性と一致する属性を定義するブロックです。リクエストが許可された属性を省略した場合、リクエストはポリシーによって許可されますが、許可されたブロックに存在しない属性が含まれている場合、リクエストを拒否します。
許可された属性は、required
としてマークできます。true の場合、属性がリクエストで定義されていることを強制します。対応するフィールドも定義されている場合にのみ、フィールドを required
としてマークできます。required
フィールドは、isCA
または usages
では使用できません。
次の 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/v1alpha1kind: CertificateRequestPolicymetadata:name: my-policyspec: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: trueisCA: falseusages:- "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 以降では、Common Expression Language (CEL) を使用して、より高度な許可されたリクエスト属性検証ルールを定義できるようになりました。この機能を追加した主な動機は、許可されたリクエスト属性値をリクエスト名前空間の関数として有効にすることでした。しかし、CEL は小さなプログラミング言語であるため、検証ルールは allowed
属性値の指定における基本的なワイルドカードサポートを補完または置き換えることもできます。
リクエスト属性値は、self
変数の式で利用できるようになります。多値のリクエスト属性の場合、検証は値ごとに 1 回実行されます。self
変数と同様に、approver-policy は、検証するリクエストを表す cr
変数を提供します。この変数はオブジェクト型であり、執筆時点では、namespace
と name
の 2 つのフィールドのみがあります。
以下では、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 言語定義が役立つ場合があります。
制約
制約とは、リクエストが持つことができる属性を制限するために使用されるブロックです。制約が定義されていない場合、その属性は「すべて許可」とみなされます。
以下は、CertificateRequestPolicy のサポートされているすべての制約フィールドを含む例です。
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: my-policyspec:...constraints:minDuration: 1hmaxDuration: 24hprivateKey:algorithm: RSAminSize: 2048maxSize: 4096...
セレクター
セレクターは必須フィールドであり、評価のためにCertificateRequestPolicyをCertificateRequestと照合するために使用されます。CertificateRequestPolicyは、リクエストの評価対象とするために、CertificateRequestを選択(つまり、一致)する必要があります。
⚠️ ポリシーをリクエストに対して評価対象とするためには、ユーザーは依然としてRBACによって拘束される必要があることに注意してください。
approver-policyは、リクエストのissuerRef
とnamespace
による選択をサポートします。
issuerRef
またはnamespace
セレクターの少なくともいずれかは、空({}
)に設定した場合でも、定義する必要があります。両方のセレクターが定義されている場合、ポリシーによってリクエストが評価されるためには、両方のセレクターがCertificateRequestで一致する必要があります。
issuerRef
issuerRef
CertificateRequestPolicyセレクターは、CertificateRequestの対応するissuerRef
スタンザに基づいて選択を行います。
issuerRef
の値はワイルドカード"*"を受け入れます。issuerRef
が空のオブジェクト{}
に設定されている場合、ポリシーはすべてのリクエストと一致します。
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: my-policyspec:...selector:issuerRef:name: "my-ca"kind: "*Issuer"group: "cert-manager.io"
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: match-all-requestsspec:...selector:issuerRef: {}
namespace
namespace
CertificateRequestPolicyセレクターは、CertificateRequestが作成されたNamespaceに基づいて選択を行います。セレクターは、matchNames
またはmatchLabels
のいずれかで定義できます。
matchNames
は、Namespaceの名前と一致する文字列のリストを受け取ります。ワイルドカード"*"を受け入れます。
matchLabels
は、CertificateRequestが作成されたNamespaceのラベルと一致するキーと値の文字列のリストを受け取ります。matchLabels
の動作の詳細については、Kubernetesドキュメントを参照してください。
namespace
が空のオブジェクト{}
に設定されている場合、ポリシーはすべてのリクエストと一致します。
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: my-policyspec:...selector:namespace:matchNames:- "default"- "app-team-*"matchLabels:foo: barteam: dev
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: match-all-requestsspec:...selector:namespace: {}
プラグイン
プラグインは、コンパイル時にapprover-policyに組み込まれる外部承認者です。プラグインは、既存のチェックでは提供できない特別な機能をユーザーが必要とする場合に、既存のポリシーチェックの拡張機能として使用されるように設計されています。
プラグインは、CertificateRequestPolicyのspec
のブロックとして定義されます。
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: pluginsspec:...plugins:my-plugin:values:val-1: key-1
コミュニティからの既知のプラグイン
CEL approver-policy plugin(アーカイブ済み。approver-policyでのCELサポートが利用可能になりました)
外部承認者ポリシープラグインを実装する場合は、https://github.com/cert-manager/example-approver-policy-pluginにある実装例を参照してください。
approver-policy用のプラグインを実装しましたか?cert-managerウェブサイトプロジェクトでプルリクエストを開いて、このページからプラグインへのリンクを追加してください。
APIリファレンス
📖 approver-policy APIリファレンスをお読みください。