コンテナイメージの署名:Sigstore、Notary、Docker Content Trustを比較
Hrittik Roy
2023年9月26日
0 分で読めます現代のソフトウェアエコシステムでは、コンテナ化がアプリケーションのパッケージ化とデプロイに広く使われるようになりました。この傾向とともに、ソフトウェアサプライチェーンのセキュリティ確保は、あらゆる規模の企業にとって重要な課題となっています。中間者(MITM)攻撃のリスクを軽減し、イメージの真正性と鮮度を検証するための署名や検証など、ベストプラクティスを実践することは、ソフトウェアサプライチェーンの完全性を守るうえで重要な役割を果たします。
コンテナイメージの署名では、暗号技術を使ってイメージを特定のエンティティや組織に結び付け、信頼の連鎖を構築します。これにより、イメージ内のコードの真正性と完全性を確保できます。
また、コンテナイメージに署名することで、所有者と責任の所在を明確にできます。署名は監査にも役立ち、組織がイメージの出所や変更履歴を追跡・検証し、特定のコンプライアンス基準や規制を適用するのに役立ちます。
この記事では、人気の高い3つのコンテナ署名ソリューション、Sigstore Cosign、Notary v2、Docker Content Trust(DCT)(別名Notary v1)を比較します。それぞれの機能や性能、コンテナイメージのサプライチェーン保護への適性について解説します。最後に、ツールの1つをワークフローに組み込む方法を学べるチュートリアルも紹介します。
コンテナ署名ツール
イメージを安全に署名するためのツールは数多くあります。特に注目すべきものはCosign、Notary、DCTの3つで、それぞれ仕様や要件が異なります。
Sigstore Cosign
Cosignは、ソフトウェアの署名、検証、保護をシンプルかつ安全に行えるツールです。Apache License 2.0のもとで提供され、Sigstore標準に基づいて構築されており、コンテナイメージの完全性と真正性を確保します。Cosignの人気は急速に高まっており、GitHubでは3,400以上のスターを獲得しています。
Cosignは、Sigstore Fulcio認証局とRekor不変透明性ログ、認証済みOpenID Connect(OIDC)IDを使った、鍵不要の署名に対応していることで知られています。この方式ではインフラストラクチャが意識されないため、ユーザー自身が鍵を管理・維持する必要はありません。Cosignは一時的な鍵を生成してプロセスを簡素化し、署名済みイメージやBLOBの真正性を簡単に検証・署名できるようにします。
Docker Content Trust
Docker Content Trust(DCT)は2015年にDockerが開発し、その後Cloud Native Computing Foundation(CNCF)にNotaryプロジェクトとして寄贈されました。現在はインキュベーション段階のプロジェクトです。
DCTを使うと、コンテナイメージに署名して検証し、クライアント側または実行時の検証によって、特定のイメージタグの完全性と真正性を確保できます。
Notary v1では、レジストリに公開鍵を追加し、対応する秘密鍵でイメージに署名してからアップロードします。ユーザーは、レジストリのコマンドグループから取得したデータと公開鍵を照合して、イメージを検証できます。また、リリースプロセスの一環としてコンテンツに署名することで、ソフトウェアサプライチェーンを自動化できます。
Notary v2
Notary v2の署名システムは、従来の制約を克服することを目指した、改良版です。NotationとNotary v2を使えば、仕様に準拠した独自の実装を構築し、署名や検証のワークフローに組み込んで、複数のアーティファクト(たとえば、コンテナイメージ、ソフトウェア部品表、スキャン結果)に署名できます。これは、イメージ署名の使いやすさ向上や、複数のレジストリへの対応、従来のv1実装でレジストリ間のイメージ移動に伴う問題の解決を目指して、2019年12月に設立されたグループの支援により実現しました。
Notary v2は比較的新しく、2022年12月にリリースされました。Open Container Initiative(OCI)のイメージやレジストリアーティファクトの署名・検証に対応する、業界横断・レジストリ横断の仕様を目指しています。プロジェクトは現在も開発中で、今後新たな機能が追加される予定です。
Cosign、Notary v2、Docker Content Trustの比較
この記事では、最適なツールを選ぶための重要な特性を4つ紹介します。
信頼委任モデルとは、アーティファクトとレジストリの完全性および真正性を確保するため、信頼を確立して配布する仕組みです。
透明性と監査可能性とは、システム内の操作や変更を可視化して検証し、説明責任と完全性を確保できることです。
使いやすさには、署名ツールのシンプルさや使い勝手の良さが含まれ、容易な導入と統合を可能にします。
コミュニティのサポートには、システムを取り巻くコミュニティの関与や協力、提供されるリソースの充実度が含まれ、継続的な開発と支援につながります。
これらの要素はそれぞれ、各ツールの有効性に大きく影響します。以降のセクションでは、各カテゴリについて、これらの要素を基準にツールを評価します。
信頼委任モデル
Cosignは、Sigstoreプロジェクトが提供する証明書と公開鍵から成る信頼の起点を用いた、分散型のフェデレーション信頼委任モデルを採用しています。鍵素材の配布と取得にはThe Update Framework(TUF)を使用します。また、Sigstoreの信頼の起点を使ってRekorへの包含証明を検証します。
一方、Notary v2とv1は、TUFを使ってイメージを配布する階層型信頼委任モデルを採用しています。このモデルでは、信頼できるIDを保存するためにトラストストアを使用します。
v2でアーティファクトを生成する場合、ユーザーや管理者が信頼ポリシーを設定し、どのIDを信頼するかを定義します。署名済みアーティファクトの真正性は、トラストストア内のIDと信頼ポリシーに基づく信頼によって判断されます。
v1では、DCTはイメージタグの信頼の起点としてオフライン鍵を使用し、リポジトリ鍵やタグ付け鍵に信頼を委任します。サーバー管理の鍵も追加のセキュリティを提供します。このモデルでは、システム内で異なるレベルの信頼を設定し、さまざまなセキュリティポリシーやアクセス制御を適用できます。
まとめると、CosignはSigstoreを信頼の起点とする分散型のフェデレーション信頼を重視しているため、信頼委任に適した選択肢です。タグベースの検出方式を実装し、ほとんどの本番環境向けレジストリに対応しています。一方、複数のレジストリに対応する必要がなく、レジストリ間の相互運用性も不要な場合は、Notary v1を選ぶとよいでしょう。相互運用性が必要であれば、v2なら複数のレジストリ間で信頼を分散できます。
透明性と監査可能性
透明性と監査可能性の面では、Sigstoreはすべての署名を公開レジストリに保存することで、ソフトウェアアップデートの安全性と透明性を確保します。これにより、組織はソフトウェアアップデートの真正性を簡単に検証できます。また、Rekorを使えば、すべての署名イベントを公開監査できます。これは、ソフトウェアサプライチェーンの説明責任と信頼性の確保に役立ちます。
一方、DCTにはいくつかの欠点があります。1つのイメージに付けられる署名は1つだけです。そのため、Docker Hub上のイメージにベンダーがすでに署名している場合、自社での利用に適していることを示す署名を追加できません。これにより、ソフトウェアサプライチェーンに対する柔軟性や制御が制限される可能性があります。
一方、Notary v2は、エコシステム全体の信頼を維持するため、より包括的なアプローチを採用しています。Docker Hubから直接取得したイメージは本質的に安全だという前提に疑問を投げかけます。複数の署名に対応することで、Notary v2はイメージの安全性を検証できるようにし、組織独自の承認印も記録できるため、ソフトウェアサプライチェーンへの信頼をさらに高めます。
この記事の公開時点では、Notary v2 1.0.0はリリース候補版の段階にあり、まだ一般公開されていません。そのため、新しく複雑な環境では、成熟度とインテグレーションの豊富さからSigstoreのほうが適している場合があります。
使いやすさ
Cosignは、鍵管理と署名のプロセスを簡素化し、使いやすさを追求しています。また、開発者はイメージのビルド時に既存のワークフローへ簡単に組み込めます。鍵不要の署名により鍵管理の複雑さがなくなり、Cosignが生成する秘密鍵と公開鍵のペアを使うため、導入手順もシンプルです。
一方、NotaryはDockerコンテナエコシステムとシームレスに統合され、コンテナの署名や検証に使えるコマンドラインツールとAPIを提供します。ただし、比較的新しいため、Notation以外のクライアントへの対応は限られています。また、Notaryのどちらのバージョンでも多くの鍵を管理する必要があるため、TUFについて十分な知識が求められます。
一方、DCTはDockerと密接に統合されているため、直感的なコマンドでイメージの署名や検証を簡単に有効化できます。ただし、レジストリ間では機能せず、Notaryサーバーを使わずに公開イメージを取得してプライベートレジストリにプッシュすると、署名データが失われます。また、Notaryサービスをセットアップするには、Notaryサーバー、Notary署名者、Notaryクライアント、MySQLデータベースに加え、Notaryサーバーと署名者の間でmTLS(相互TLS)を構成する必要があります。多くの場合、追加の作業が必要であり、v2の普及に伴って廃止されると言われています。
使いやすさでは、ユーザーフレンドリーな設計、シンプルな鍵管理、既存ワークフローとの統合により、Cosignが優位に見えます。Notary v2も統合機能やコマンドラインツールを提供しますが、セットアップや管理にはDCTより多くの作業と知識が必要です。一方、docker trustが同梱されており、非常に簡単に使えます。
コミュニティのサポート
すべてのプロジェクトがCNCF傘下にあり、コミュニティから十分なサポートを受けています。ただし、Cosignは業界パートナーからも支援を受けており、活発なコントリビューターコミュニティが継続的な開発、サポート、協力を支えています。Notaryも強力なコミュニティに支えられたオープンソースプロジェクトで、Dockerエコシステムで広く使われており、多くのユーザーからの貢献やフィードバックを得ています。v2プロジェクトは比較的新しいため、ドキュメントやチュートリアルのコンテンツが他のソリューションほど充実していません。そのため、NotationのようなCLIでv2を学び、使い始めようとする新規ユーザーにとって、導入の妨げとなる可能性があります。
DCTはDockerプラットフォームの一部であり、広範なDockerコミュニティの支援を受けています。大きな支持を集めており、ツールやインテグレーションが充実したエコシステムを持つため、簡単に有効化できます。また、導入に役立つチュートリアルも数多く公開されています。
そして、勝者は…
どのツールを選ぶべきかは、組織やシステムの具体的な要件、優先事項、制約によって異なります。Sigstoreは、イメージに加えてHelmチャートなど、さまざまなアーティファクトの安全で透明性の高いソフトウェアアップデートを重視する組織に適しています。優れたコミュニティサポートと、レジストリ間の相互運用性などの機能を備えており、多くの組織にとって有力な選択肢です。さらに、ほとんどのコンテナレジストリがこの署名形式に対応しています。
一方、シンプルさとDockerとのシームレスな統合が不可欠な場面では、DCTが優れています。Dockerとの緊密な統合と直感的なコマンドにより、複雑な信頼モデルやレジストリ間の相互運用性を必要とせず、イメージの署名と検証を簡単に行えます。
Notary v2は、ソフトウェアサプライチェーンの信頼性を維持するためのより包括的なソリューションであり、DCTの制約に対処します。ただし、まだ開発中のプロジェクトであるため、組織全体への導入には慎重な検討と計画が必要になる場合があります。セットアップやTLS証明書、TUFキーの管理は複雑で、習得に時間がかかるうえ、適切に設定されていないと運用上の負担になりかねません。また、すべてのレジストリが対応しているわけではないため、利用する場合はある程度の妥協が必要になることもあります。
Cosignで署名する方法
Cosign、Notary、DCTについて理解が深まったところで、次はそのツールの1つであるCosignを使ってみましょう。この例では、シンプルなDocker registry:2参照イメージを使って、簡易レジストリを実行します。実際の環境では、Harbor、Amazon ECR、Docker Hubなどのマネージドレジストリを使用します。
前提条件
始める前に、次のツールをインストールしてください。
両方のツールをインストールしたら、始めましょう。
レジストリをセットアップする
イメージを保存するには、Docker registry:2参照イメージのレジストリインスタンスを作成します。
注:ここでは競合を避けるために、ローカルポート15000にバインドしています。特に、最近のリリースでAirDropサービスにポート5000が使用されていたMac OSでは注意が必要です。必要に応じて、ワークステーションで利用可能なポートに変更できますが、以降のコマンドでも同じポートを使用してください。
レジストリにイメージをプッシュする
Dockerイメージに署名してレジストリにプッシュするには、次の手順に従います。
パブリックレジストリから任意のイメージをプルします(この例ではBusyBoxを使用します)。
このコマンドは、パブリックDockerレジストリからBusyBoxイメージを取得します。
次に、ローカルレジストリのIPアドレスを使ってイメージにタグを付けます。
続いて、イメージをアップロードするため、署名済みイメージをHarborレジストリにプッシュします。
このコマンドは、docker pushコマンドを使用して、タグ付けされたイメージをHarborレジストリにプッシュします。実行結果には、次のようなsha256ダイジェストが表示されます。
sha256:から文字列の末尾まで、ダイジェスト値をコピーします(後ろに続くスペースや「size」は含めません)。これはイメージの暗号学的ハッシュで、次の手順で署名対象が直前にプッシュしたイメージと完全に同一であることを確認するために使います。
これらの手順を完了すると、Dockerイメージがレジストリに正常にプッシュされ、環境内でのデプロイや配布に利用できるようになります。ただし、まだ署名が必要です。
プッシュしたイメージに署名する
Cosignを使ってプッシュ済みのコンテナイメージに署名する前に、秘密鍵と公開鍵を生成します。次のコマンドを実行して署名用の鍵ペアを生成してください。
前のコマンドを実行すると、秘密鍵のパスワードを求められます。パスワードを入力して確認してください。秘密鍵はcosign.keyというファイルに、公開鍵はcosign.pubに保存されます。秘密鍵と設定したパスワードは安全に保管してください。
次に、cosign signコマンドを使って、次のようにイメージに署名します。
ディレクトリを変更した場合は、cosign.keyを秘密鍵ファイルへのパスに置き換え、[sha256 digest]を前の手順でコピーした完全なハッシュ値に置き換えてください。秘密鍵のパスワードを求められるので、入力して続行します。
Cosignでイメージに署名することで、イメージの鮮度、真正性、完全性を保証できます。これによりコンテナイメージのセキュリティがさらに強化され、ソフトウェアサプライチェーンへの信頼を維持できます。
署名済みイメージを検証する
署名済みイメージを検証するには、組み込みのcosign verifyコマンドを次のように実行します。
プライベートレジストリの使用やSigstoreプロジェクトの利用規約への同意について、Yes/No形式の質問がいくつか表示されることがあります。内容を確認して回答してください。
署名の検証に成功すると、イメージが安全に署名され、検証済みであることを示す確認メッセージが表示されます。確認メッセージは次のようになります。
この確認メッセージは、組織の強固なセキュリティ体制を維持するうえで重要です。
その他のアーティファクトに署名する
コンテナイメージはソフトウェアサプライチェーンの重要な要素ですが、エンドツーエンドのセキュリティを確保するには、ほかのソフトウェアアーティファクトへの署名も同様に重要です。コンテナイメージに加えて、実行ファイル、Java Archive(JAR)ファイル、パッケージ、ソフトウェア部品表(SBOM)など、さまざまな種類のソフトウェアアーティファクトも署名によるメリットを得られます。たとえば、Cosignを使ってSBOMに署名する方法を解説したチュートリアルがあります。
その他のアーティファクトに署名することで、完全性、鮮度、来歴といった、すでに説明したメリットが得られ、コンプライアンス、監査、参照への対応にも役立ちます。ただし、コンテナイメージへの署名ほど簡単ではない場合があります。たとえばSBOMの場合、レジストリにホストされたコンテナイメージにSBOMを添付したうえで、Cosignを使って署名します。
JARなどのアーティファクトには、Jarsignerなどのツールを使用できます。ただし、従来のイメージ署名よりも複雑です。鍵や署名の生成、保管、移動、安全な使用など、追加の手順が必要になるためです。
まとめ
さまざまなアーティファクトへの署名には複雑さが伴うこともありますが、こうした手順はソフトウェアアーティファクトのセキュリティ、完全性、コンプライアンスを強化するために実施されるものです。デジタル署名を取り入れ、鍵管理のベストプラクティスに従うことで、組織は信頼を確立し、コンプライアンス要件を満たし、監査や参照に対応しながら、重大なセキュリティリスクから保護できます。
イメージの改ざんを防ぎ、セキュリティを強化する第一歩として、コンテナへの署名から始めるのがおすすめです。この記事で紹介した各種ツールは、それぞれ異なるユーザー層に適しています。どれを選ぶかは、セキュリティやコンプライアンスの基準で求められる有効性と柔軟性のレベルに応じて判断しましょう。イメージ署名を導入した後は、イメージレイヤーのセキュリティスキャンや監査を支援するソリューションを活用できます。
たとえば、Snykは、開発者にとってシームレスなエクスペリエンスを重視する開発者向けセキュリティプラットフォームです。コンテナイメージのスキャン機能を備えており、Dockerイメージに含まれるパッケージの既知の脆弱性を特定できます。これにより、イメージをDocker Hubなどのレジストリにプッシュする前に、脆弱性を事前に検出して対処でき、全体的なセキュリティ体制の強化につながります。
開発者ファーストのコンテナセキュリティ
Snykは、コンテナイメージとKubernetesワークロードの脆弱性を検出し、自動的に修正します。
