TT Lab
はじめる
学ぶ 学習パス コース

KCA — Kyverno認定アソシエイト

署名検証ポリシーと資格情報を立てる

TT Labで続きを見る

目標

cosignの署名とattestationを検証するKyvernoポリシーを書き、KyvernoとPodがそれぞれプライベートレジストリにアクセスするために必要な認証情報のリソースを、実際のクラスターに作成します。

なぜ重要なのか

署名検証ポリシーは、文法よりも運用条件のほうが難しいものです。署名があるか、その署名を問い合わせられるか、問い合わせた署名が信頼する主体のものか、がそれぞれ別の失敗モードで、症状はどれも「Podが起動しない」で同じです。特にattestors.countを忘れるとentriesのすべてが通過しなければならなくなるため、鍵を追加した途端にすべてが止まり、mutateDigestを有効にすると、タグを上書きしてPodを再作成していたパイプラインが静かに無力化されます。このラボでは、そうした落とし穴をマニフェストの上で先に踏んでみます。

ステップ

  1. /root/kca-verify/ディレクトリを作成し、verify-keys.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-verify-images、spec.rules[0].nameとしてverify-signatureを書いてください。verifyImages[0].imageReferencesに10.0.0.202/platform/*を入れ、attestors[0].entries[0].keys.publicKeysにBEGIN PUBLIC KEYで始まるPEM形式の公開鍵を入れてください。
  2. 同じattestors[0]でcountを1にし、entriesを2つにしてください。2つ目の項目はkeylessで、urlはhttps://fulcio.sigstore.dev、rekor.urlはhttps://rekor.sigstore.dev、issuerはhttps://token.actions.githubusercontent.comにし、subjectには.github/workflows/を含むワークフローのパスを書いてください。
  3. 同じverifyImages[0]でrequired、verifyDigest、mutateDigestをすべてtrueにし、skipImageReferencesに10.0.0.202/platform/legacy-*を入れてください。そしてspec.webhookConfiguration.timeoutSecondsを20から30の間の値にし、非推奨(deprecated)のspec.webhookTimeoutSecondsは使わないでください。
  4. /root/kca-verify/verify-attestations.yamlにkindとしてClusterPolicyを書き、verifyImages[0].attestationsに2つの項目を入れてください。1つはtypeがhttps://slsa.dev/provenance/v1で、conditions[0].all[0].keyでビルダーの身元を検査するもの、もう1つはtypeがhttps://cyclonedx.org/bom/v1.4で、conditions[0].all[0].keyでlog4j-coreコンポーネントのバージョンを検査するものです。
  5. /root/kca-verify/allowed-registries.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-allowed-registriesを書いてください。spec.rules[0].validate.foreach[0].listはrequest.object.spec.[initContainers, containers][]にし、波括弧で囲まないでください。deny.conditions.all[0].operatorはAnyNotIn、valueのリストに10.0.0.202/platform/*を入れ、validate.failureActionはEnforceにしてください。
  6. クラスターにネームスペースkca-verifyを作成し、その中にSecret harbor-credを実際に作成してください。typeはkubernetes.io/dockerconfigjsonで、サーバーは10.0.0.202です。
  7. 同じネームスペースにServiceAccount kca-deployerを作成してimagePullSecretsにharbor-credを付け、Deployment kca-paymentsを実際に作成して、serviceAccountNameをkca-deployerにし、コンテナイメージを10.0.0.202/platform/payments@sha256:の後ろに64桁の16進数を付けた形で書いてください。

参考

静的な鍵によるverifyImages

/root/kca-verify/ディレクトリを作成し、verify-keys.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-verify-images、spec.rules[0].nameとしてverify-signatureを書いてください。verifyImages[0].imageReferencesに10.0.0.202/platform/*を入れ、attestors[0].entries[0].keys.publicKeysにBEGIN PUBLIC KEYで始まるPEM形式の公開鍵を入れてください。

verifyImagesはルールの中の配列で、各項目がimageReferencesとattestorsを持ちます。公開鍵はPEM文字列を複数行で入れます。

keylessの追加とcountの意味

同じattestors[0]でcountを1にし、entriesを2つにしてください。2つ目の項目はkeylessで、urlはhttps://fulcio.sigstore.dev、rekor.urlはhttps://rekor.sigstore.dev、issuerはhttps://token.actions.githubusercontent.comにし、subjectには.github/workflows/を含むワークフローのパスを書いてください。

entriesを増やしただけでは、すべての項目が通過しなければなりません。鍵の入れ替え期間を無停止で乗り切るには、いくつ通過すればよいかを明示する必要があります。

ダイジェストの固定と例外、そしてタイムアウト

同じverifyImages[0]でrequired、verifyDigest、mutateDigestをすべてtrueにし、skipImageReferencesに10.0.0.202/platform/legacy-*を入れてください。そしてspec.webhookConfiguration.timeoutSecondsを20から30の間の値にし、非推奨(deprecated)のspec.webhookTimeoutSecondsは使わないでください。

3つのブール値は、それぞれ検証の強制、ダイジェスト使用の強制、タグのダイジェストへの置き換えを意味します。例外はポリシーを複製せず、専用のフィールドに書いてください。レジストリへの往復が入るポリシーは、Webhookのタイムアウトのデフォルト値では足りません。

provenanceとSBOMの条件

/root/kca-verify/verify-attestations.yamlにkindとしてClusterPolicyを書き、verifyImages[0].attestationsに2つの項目を入れてください。1つはtypeがhttps://slsa.dev/provenance/v1で、conditions[0].all[0].keyでビルダーの身元を検査するもの、もう1つはtypeがhttps://cyclonedx.org/bom/v1.4で、conditions[0].all[0].keyでlog4j-coreコンポーネントのバージョンを検査するものです。

attestationsは、typeでどの陳述かを選び、conditionsでその内容を検査します。署名だけを見ても、誰がビルドしたかは検査していないことになります。

許可レジストリの検査

/root/kca-verify/allowed-registries.yamlにkindとしてClusterPolicy、metadata.nameとしてkca-allowed-registriesを書いてください。spec.rules[0].validate.foreach[0].listはrequest.object.spec.[initContainers, containers][]にし、波括弧で囲まないでください。deny.conditions.all[0].operatorはAnyNotIn、valueのリストに10.0.0.202/platform/*を入れ、validate.failureActionはEnforceにしてください。

foreachのlistは、波括弧で囲みません。初期化コンテナまで一緒に巡回する必要があり、許可リストの外にあるときに拒否する演算子を選んでください。

レジストリ認証情報のSecret

クラスターにネームスペースkca-verifyを作成し、その中にSecret harbor-credを実際に作成してください。typeはkubernetes.io/dockerconfigjsonで、サーバーは10.0.0.202です。

ここからは実際のクラスターです。レジストリ専用のSecretのタイプがあり、kubectlにはそれを作成するサブコマンドがあります。

ServiceAccountとダイジェスト固定のデプロイ

同じネームスペースにServiceAccount kca-deployerを作成してimagePullSecretsにharbor-credを付け、Deployment kca-paymentsを実際に作成して、serviceAccountNameをkca-deployerにし、コンテナイメージを10.0.0.202/platform/payments@sha256:の後ろに64桁の16進数を付けた形で書いてください。

ServiceAccountにimagePullSecretsを付けると、そのアカウントで起動するPodが引き継ぎます。イメージはタグではなくダイジェストで固定された形でなければならず、sha256は64桁です。