監査証跡が成立する条件
一言でいうと
監査証跡には、実行した内容の識別子、信頼できる生産の証拠、時点ごとのデプロイ記録が必要です。秘密の値をたくさん保存したからといって、証拠が良くなるわけではありません。
なぜタグ1つでは足りないのか
タグは別のイメージに移動できますが、digestは内容の識別子です。したがって、望むデプロイをdigestで固定し、スキャン・署名の対象と結びつけるのがよいです。digestそのものが、安全性、作成者、ソースのコミットを証明するわけではありません。Kubernetesのイメージ
タグでデプロイしたからといって、現在のイメージをまったく調べられないわけではありません。status.containerStatuses[].imageIDには、ランタイムが識別したイメージの情報があり、宣言したイメージと異なることがあります。形式とdigestの意味は、ランタイム・イメージの種類に合わせて確認します。現在の参照は、すでに削除されたPodの過去の状態までは復元しないため、デプロイ当時の識別子と時刻も保存します。Kubernetes ContainerStatusの原本
どう動くのか
4つの証拠をつなげます
| 証拠 | 確認すること | 単独では証明できないこと |
|---|---|---|
| イメージのdigest | 検証・デプロイの対象の同一性 | 脆弱性がないこと、ソースのコミット |
| イメージの署名 | 信頼ポリシーに合う署名者の署名 | その署名者が実際のビルダーであるという事実 |
| SBOM | コンポーネントの一覧と、対象との結びつき | 一覧の完全性・作成者の信頼性 |
| ビルドprovenance | 対象、ビルダー、入力とビルドの過程 | 信頼していないビルダーの誠実さ |
イメージの署名とSBOMの署名は別です。イメージの署名が有効でも、そばに置かれた任意のSBOMファイルまで認証されるわけではありません。たとえば、SBOMを含むattestationは、署名の検証だけでなく、subjectのdigestが対象と同じか、期待したpredicateTypeかを確認します。ビルドprovenanceも、信頼するビルダーと、期待するソース・ビルドの条件を検証する必要があります。SLSAアーティファクトの検証
Sigstoreのcosign verifyとcosign verify-attestationは、検証の対象が異なります。キーレス検証では、許可した証明書のIDとOIDC発行者を、具体的に制限します。暗号学的に署名が合っていることと、自社のリリース主体が署名したことは、別の判断です。Sigstoreの検証案内
スキャンレポートには、対象のdigest、スキャナー・脆弱性DBのバージョン、検査の時刻と例外をまとめます。レポートの生成に成功しただけでは、デプロイゲートにはなりません。基準違反と検査ツールのエラーを区別しつつ、どちらも適切にデプロイを止めるかを確認します。新しい脆弱性が見つかれば、同じイメージも再評価する必要があるため、ビルド当時の通過を、永久に安全という判定として使いません。
Secretの本文を監査ログに複製しません
Metadataは、ユーザー・時刻・リソース・動作などの記録を残しますが、リクエスト・レスポンスの本文は残しません。Requestはリクエスト本文を、RequestResponseは両方の本文を含みます。Secretを詳細なレベルで記録すると、機密性のある内容がログに複製されることがあります。Kubernetesの監査レベル
Secretのbase64は暗号化ではないため、エンコードされた値も露出です。Secretの参照権限を絞っても、ログの読者に本文が見えれば、別の経路で流出します。ConfigMapやPodの仕様に、秘密を直接入れることも避ける必要があります。Secret管理の原則
次は、本文を残さない出発点の例です。kubectl applyするワークロードではなく、APIサーバーの監査ポリシーファイルです。実際に有効にするには、ポリシーファイルと、ログ・Webhookの保存経路の設定が必要で、マネージドサービスでは、提供者の設定を確認します。本番の設定を、そのまま置き換えないでください。
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: Metadata
最初は、すべてのリクエストをMetadataで記録します。あとで詳細なルールを追加する場合でも、機密リソースの保護ルールより前に、広範な本文記録のルールを入れません。最初に一致するルールが適用されるため、後ろの保護ルールで前の決定を上書きすることはできません。サブリソースと、ほかのAPIグループの機密データも、別に検討します。監査ポリシーAPIの契約
Metadataも、公開ログではありません。リクエストURIや監査アノテーションなどに、機密性のある情報を入れず、ログの閲覧・持ち出しの権限、保存期間、完全性、収集失敗のアラートを管理します。本文を省略することは、ログ全体から秘密が自動的に取り除かれることを保証しません。
現場での姿
例のシナリオ: 調査の担当者は、秘密の値は必要ないのに、誰が本番のSecretを読んだかは知る必要があります。自分が所有する分離された環境で、実際の認証情報ではない合成のマーカーを使って、作成・参照・削除のリクエストを作り、該当のリクエストのユーザー・動作・対象・レスポンス結果が残っているかを確認します。同時に、requestObjectとresponseObject、合成マーカーの原文・エンコード値がないかも検査します。記録が空だと、2つ目の条件だけが通過するため、リクエストの証拠が存在するかを先に確認する必要があります。
収集の経路が正常であることも、別の条件です。APIサーバーのローカルファイルにはあるのに、中央のストレージにはないなら、中央の検索でインシデントを調査できません。既知のテストリクエストを最後まで探してみることが、コレクターの画面の緑ランプよりも直接的な証拠です。
次のクイズで確認すること
ポリシーの範囲の漏れ、NetworkPolicyとmTLSの違い、Secretの監査レベル、digestとprovenance、SBOMの結びつきを判断します。
実際に確認した範囲
2026-09-11、分離されたk3s v1.36.4+k3s1のプローブで、合成Secretの作成・参照・削除と、許可されていないユーザーの参照を実行しました。Metadataでは、4つのリクエストの証拠だけが残り、詳細なルールを前に置くと合成の本文が露出し、修正後は、また本文が消えました。Secretの記録をNoneで無効にした場合は、別の/versionの突き合わせリクエストは記録されますが、Secretの証拠がなく、検証ツールが失敗しました。
リポジトリのscripts/probe_cnpe_audit.pyとtests/test_cnpe_audit_probe.pyに、再現と反例の検査を残しました。この確認は、単一ノードのローカル監査ファイルに限られます。中央収集・ログの完全性・機密リソース全体のポリシーや、本番クラスターの監査設定を、検証・変更したという意味ではありません。続けて、個人VMで、秘密の露出・Metadataの復旧・Noneによる証拠の欠落を、直接再現する8ステップのラボを行います。収集時点の抜粋と、現在のAPIの新しい参照を合わせて確認しますが、この資料が中央の監査ストレージの完全性を保証するわけではありません。