サプライチェーンの「信頼」をコードで定義する:Cosignによるコンテナ署名の深淵
コンテナセキュリティを語る際、多くのエンジニアは「脆弱性スキャン」に目を奪われる。だが、CI/CDパイプラインをどれほど堅牢に構築しても、その終端であるコンテナランタイムが「何を実行しているのか」を保証できなければ、それは砂上の楼閣だ。
今日、攻撃者が狙うのはアプリケーションのバグだけではない。リポジトリの乗っ取り、あるいは中間者攻撃によるイメージの差し替えだ。本稿では、SigstoreのCosignを用い、サプライチェーンの最終防衛ラインを構築するアーキテクチャの核心を解説する。
—
1. なぜ「署名」が不可欠なのか:メモリ破壊から改ざんまで
Dockerイメージをレジストリからプルする際、我々は暗黙的に「そのイメージがビルドされたものと同一である」と信じている。しかし、TLSの証明書検証だけでは不十分だ。レジストリの認証情報を奪取された場合、攻撃者は悪意あるバイナリを混入させ、コンテナ起動時にメモリ上のヒープ領域を汚染するようなパッチを当てることも可能だ。
我々アーキテクトが対峙すべきは、ランタイム上の「想定外のコード実行」だ。Cosignによる署名は、単なるチェックサムの比較ではない。秘密鍵を用いた非対称暗号により、「誰が」「いつ」ビルドしたかを不可逆的に紐付ける。
2. Cosignを用いた署名プロセスの実装
まず、鍵ペアを作成し、署名を付与するプロセスをコード化する。ここでは、KMS(Key Management Service)と連携した運用を前提とする。
# 1. 署名用の鍵ペアを作成(実際にはKMSのキーIDを利用すべき)
cosign generate-key-pair
# 2. コンテナイメージに署名を付与
# --key: 秘密鍵、またはKMSのキーリファレンスを指定
# 署名データは自動的にレジストリへイメージタグの別名としてプッシュされる
cosign sign --key cosign.key my-registry.com/app:v1.0.0
# 3. 署名の検証(デプロイメント時に必須)
# 公開鍵を用いて、イメージの完全性を確認する
cosign verify --key cosign.pub my-registry.com/app:v1.0.0
ここで重要なのは、cosign signが行う処理の内容だ。Cosignは署名情報をOCIレジストリのタグとして格納する。つまり、元のイメージを改ざんせずに、その横に「真正性の証明書」を置く構造をとっている。これは低レイヤの通信プロトコル仕様においても、既存のレジストリインフラを汚染しないスマートな設計だ。
3. Kubernetes Admission Controllerによる強制検証
署名しただけでは意味がない。悪意あるイメージがデプロイされないよう、KyvernoやPolicy Controllerを用いて、クラスター側で強制検証を行う必要がある。
以下は、Kyvernoを用いたポリシーの例だ。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce # 検証に失敗したイメージのデプロイを遮断
rules:
- name: verify-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "my-registry.com/app:*" # 対象イメージ
verifyDigest: true
attestations:
- predicateType: cosign # Cosign署名を要求
publicKey: |
-----BEGIN PUBLIC KEY-----
(ここに公開鍵を記載)
-----END PUBLIC KEY-----
このポリシーを適用することで、クラスターは署名のないイメージのpod生成リクエストをすべて拒否する。たとえ攻撃者がレジストリに侵入し、イメージを差し替えたとしても、署名が一致しない限り、コンテナがメモリ空間に展開されることはない。
4. 次なる脅威:耐量子暗号への備えとガードレイル
我々が現在利用しているRSAやECDSAを用いた署名は、将来的に到来する量子コンピュータによる公開鍵の解読リスクを内包している。Sigstoreコミュニティでも議論されているが、今後はPQ-Signatures(耐量子署名)の導入が必須となる。
また、生成AIを利用したCI/CDの自動化が進む中、プロンプトインジェクションによる「意図しないコードの生成」が新たな脆弱性ベクトルとして浮上している。イメージの署名は「ビルドされたもの」を保証するが、「そのビルド内容がセキュアか」という問いには別のガードレイルが必要だ。
今、現場で求められている監査の視点:
- SBOM (Software Bill of Materials) の署名: 署名対象をバイナリだけでなく、その依存関係(SBOM)まで含めること。
- 鍵管理の分離: ビルド環境と署名環境を完全に切り離し、KMSでのロールベースアクセス制御を徹底すること。
最後に:防御は「疑うこと」から始まる
セキュリティはパッチを当てる作業ではない。システムの挙動を厳密に定義し、その定義から逸脱するものを容赦なく排除する「規律」だ。コンテナの署名は、その規律をソフトウェアレベルで強制するための最も強力なツールである。
「信頼できるソース」という言葉を信じるな。Cosignを使って、暗号学的な事実として証明させるのだ。それが、泥臭いインシデントハンドリングを繰り返さないための、我々エンジニアの責務である。
コメント