コンテナの「野良イメージ」は時限爆弾だ:Cosignによるサプライチェーン・セキュリティの実装
現場でコードを書いていると、「動けば正義」という誘惑に駆られる瞬間があるだろう。だが、クラウドネイティブな環境において、その「動くもの」がどこから来たのかを疑わないのは、夜道を鍵をかけずに歩くのと同じだ。
今日は、コンテナのサプライチェーンにおける最大の盲点――「誰がビルドしたか分からないイメージの混入」を防ぐための、Cosign を使った防御の実装について話そう。
1. なぜ「署名」が重要なのか?(PoC的な視点)
攻撃者が狙うのは、CI/CDパイプラインの隙間だ。例えば、GitHub Actionsの構成ファイルに細工をして、CIの途中で悪意のあるライブラリを注入されたとする。あるいは、レジストリの認証情報を盗み出し、正規のイメージを改ざんされたイメージとすり替えられたらどうなるか。
Kubernetesクラスターがそのイメージを「レジストリにあるから」という理由だけでプルし実行すれば、数分後にはバックドアが完成している。これが「サプライチェーン攻撃」の現実だ。デジタル署名は、「このイメージは、間違いなく私の信頼するCI環境でビルドされたものだ」という数学的証明を付与する。これがない環境は、門番のいない要塞だ。
2. Cosignによる署名の実装
Cosign は、Sigstoreプロジェクトの一部で、鍵管理の煩雑さを劇的に下げてくれる。まずは自分の環境で鍵ペアを生成し、イメージに署名する流れを叩き込む。
鍵の生成
# 鍵ペアを生成(cosign.key と cosign.pub が出力される)
cosign generate-key-pair
イメージへの署名
CI/CDの最終工程で、以下のように署名を実行する。
# 環境変数に鍵のパスを指定して署名を実行
COSIGN_PASSWORD="" # 実際はシークレットマネージャーから取得すること
cosign sign --key cosign.key my-registry.com/my-app:v1.0.0
これで、レジストリにはイメージ本体とは別に、署名データが格納される。この署名がないイメージや、改ざんされたイメージは、検証プロセスで即座に弾かれることになる。
3. Kubernetesでの強制検証(Admission Controller)
署名をするだけでは不十分だ。クラスター側で「署名がないイメージは実行させない」というルールを強制しなければならない。ここで Kyverno や Policy Controller を使うのが定石だが、今回はシンプルかつ強力な検証手法を紹介する。
Admission Controller用設定(Kyvernoポリシー例)
Kubernetesクラスターに Kyverno をインストール済みであれば、以下のポリシーを適用するだけで、署名のないイメージのデプロイをブロックできる。
# policy.yaml: 署名検証ポリシー
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce # ブロックする(Auditにすればログのみ)
rules:
- name: check-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "my-registry.com/my-app:*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
# ここに生成したcosign.pubの中身を貼り付ける
-----END PUBLIC KEY-----
これを適用すると、開発者が誤って署名なしのイメージをデプロイしようとした瞬間に、Kubernetes APIサーバーが Admission webhook denied the request とエラーを返し、実行を未然に防ぐ。
4. 現場のエンジニアへ送る「泥臭い」助言
「署名を導入するとCIの速度が落ちる」という不満が出るかもしれない。だが、インシデント対応で徹夜することを考えれば、ビルドに数秒足されることなど些細なコストだ。
以下のルールをチームの標準に組み込んでくれ。
- 自動化を徹底する: 手動署名は絶対に避ける。CI環境(GitHub Actions等)のシークレットとしてCosignの鍵を管理し、ビルドパイプラインの最後で自動的に署名が行われるようにする。
- 鍵の管理こそが命:
cosign.keyが流出したら、その瞬間に攻撃者は「信頼された署名者」になれる。鍵は必ずKMS(AWS KMSやGoogle Cloud KMS)で管理し、直接ファイルとしてサーバーに置かないこと。 - 例外を作らない: 「開発環境だから」と署名をサボると、開発環境が踏み台にされ、本番環境への攻撃経路になる。一貫したポリシーを適用せよ。
セキュリティとは、完璧な製品を導入することではない。日々の運用の中で、「疑うこと」を仕組み化することだ。Cosignはそのための最強のツールの一つである。
さあ、今すぐお使いのパイプラインに署名の工程を組み込んでみてほしい。それが、君のシステムを守る一番の近道だ。分からないことがあれば、いつでも聞くように。
コメント