要求事項

このページでは、アーティファクトがSLSAレベルを満たすために必要な、全ての技術的な要求事項を扱います。

背景については IntroductionTerminology を参照してください。 要求事項の背後にある論拠をよりよく理解するためには、Threats and mitigations を参照してください。

注意: SLSAは alpha 段階です。下記の定義はまだ最終化されておらず、(特にSLSA 3-4がそうですが)今後も変更の対象になります。

要約した表

要求事項 SLSA 1 SLSA 2 SLSA 3 SLSA 4
ソース - バージョン管理されている
ソース - 検証された履歴
ソース - 無期限に保持される 18 mo.
ソース - 2人にレビューされている
ビルド - スクリプト化されたビルド
ビルド - ビルドサービス
ビルド - コードとしてのビルド
ビルド - その場限りの環境
ビルド - 隔離されている
ビルド - パラメーターレス
ビルド - 密封されている
ビルド - 再現可能
来歴 - 利用可能
来歴 - 認証されている
来歴 - サービスにより生成されている
来歴 - 偽造不可能
来歴 - 依存関係の完備
共通 - セキュリティ
共通 - アクセス
共通 - スーパーユーザー

○ = 正当化理由がある場合以外は必須

定義

一般的なSLSAのコンセプトについては Terminology も参照してください。 下記の定義はこの文書のみで使用されます。

この文書でのキーワード、「しなければならない(MUST)」「してはならない(MUST NOT)」「必要である(REQUIRED)」「することとする(SHALL)」「しないこととする(SHALL NOT)」「推奨される(RECOMMENDED)」「してもよい(MAY)」「任意である(OPTIONAL)」は、RFC 2119 で説明されている通りに解釈されます。

不変の参照(Immutable reference): 常に同一で不変のアーティファクトを指すことが保証されている識別子。 これは、利用者がアーティファクトの場所を特定できるようになっていなければならず(MUST)、完全性を保証するためにアーティファクトの内容に対する暗号学的ハッシュを含むべきである(SHOULD)。 例: git URL + ブランチ/タグ/ref + コミットID、クラウドストレージのバケットID + SHA-256ハッシュ、SubversionのURL(ハッシュなし)

来歴(Provenance): アーティファクトがどのように作成されたかについてのメタデータ。

リビジョン(Revision): 不変で一貫したソースの状態。例えば、Gitでは、リビジョンは特定のリポジトリの特定のブランチから到達可能な履歴のうちの、あるコミットである。 一つのリポジトリの中にある異なるリビジョンは異なるレベルであってもよい(MAY)。 例: あるブランチの最も新しいリビジョンはSLSA 4を満たしているが、適用範囲より前の非常に古い歴史的なリビジョンはそうではない。

強い認証(Strong authentication): アカウントとクレデンシャルの侵害に対して耐性のある認証メカニズムを使用して、特定の人物に遡って対応付けがなされている認証。 例えば、一方の要素がハードウェア・セキュリティ・キー(YubiKeyのような)である二要素認証(2FA)。

信頼された人々(Trusted persons): ソフトウェア・プロジェクトを維持する権限を付与された人物の集合。 例えば、 https://github.com/MarkLodato/dotfiles の信頼された人々はたった一人(MarkLodato)である一方で、 https://hg.mozilla.org/mozilla-central にはmozilla-centralリポジトリに書き込みアクセス権のある、信頼された人々の集合がいる。

ソースの要求事項

要求事項説明L1L2L3L4
バージョン管理されている(Version controlled)

ソースに対する全ての変更が、下記の要求に合致するバージョン管理システムで追跡されている:

  • [変更履歴] リビジョンの形で変更の履歴の記録が存在している。 それぞれの変更は次のものを含まなければならない: アップロード者と(いれば)レビュアーのアイデンティティ、レビュー(実施されていれば)と投稿のタイムスタンプ、変更の説明/正当化理由、変更の内容、親リビジョン。

  • [不変の参照] この特定の、不変のリビジョンを無期限に参照する手段がある。 gitでは、これは {repo URL + branch/tag/ref + commit ID} である。

git、Mercurial、Subversion、Perforceのような人気上位のバージョン管理システムは、この要求を満たしている。

注: これはコード、アップロード者/レビュアーのアイデンティティ、変更履歴をパブリックにすることを要求するものではない(does NOT require)。そうではなく、組織はこれらの要求が満たされている事実を証明しなければならない。この証明が十分であるかは利用者の判断に委ねられている。

“○” = 推奨(RECOMMENDED)

検証された履歴(Verified history)

リビジョンの履歴にある全ての変更が、少なくとも一つの強く認証された行為者のアイデンティティ(作者、アップロード者、レビュアー、その他)とタイムスタンプを持っている。 どのアイデンティティが検証済みであるかは明確になっていなければならず、かつそれらのアイデンティティは二段階検証やそれに類するものを使用しなければならない(例外は後述する)。

  • [最初の親の履歴] リビジョンが一つよりも多く親を持てるような、直線的でないバージョン管理システムの場合、「最初の親の履歴」のみが適用範囲となる。 言い換えると、フィーチャー・ブランチがメイン・ブランチにマージし戻された時には、マージそのものだけが適用範囲となる。
  • [履歴上の適用範囲] 既存のプロジェクトを、歴史的なリビジョンが履歴に存在していてもSLSA 3/4に合致させるために、検討中の例外がいくつかある。 今のところ、これは直近のNか月か、次のNか月に行われる将来的な変更が要求に合致することを保証するようなプラットフォームからの証明にすることを考えている。
無期限に保持される(Retained indefinitely)

リビジョンとその変更履歴は無期限に保持され、削除されてはならない。 ただし、法的またはポリシー上の要求のような、抹消のための確立された透明性のあるポリシーの対象になる場合は例外となる。

  • [不変の履歴] 複数の関係者の承認があったとしても、人間が履歴を削除したり変更できてはならない。 ただし、抹消ポリシーに従って2人以上の関係者が承認した、信頼されたプラットフォーム管理者によるものは除外される。
  • [SLSA 3のための限定された保持期間] SLSA 3(4ではない)では、ソース管理プラットフォームによって証明されている限り、保持期間を18か月に限定することが許容される。
    • 例: コミットが 2020-04-05 に行われ、保持期間の証明が 2021-01-01 に生成された場合、コミットは少なくとも 2022-07-01 まで保持されなければならない。
18か月
2人にレビューされている(Two-person reviewed)

リビジョンの履歴にある全ての変更は、提出に先立って2人の信頼された人々によって承諾されており、それらの信頼された人々のどちらも強く認証されている。 (検証された履歴 での例外事項はここでも同様に適用される)

  • 下記の組み合わせが許容される:
    • アップロード者とレビュアーが、異なる2人の信頼された人々である。
    • 異なる2人のレビュアーが信頼された人々である。
  • [異なる人々] プラットフォームは、2人の人物によるレビューという要求をバイパスするために異なるアイデンティティを使う人がいないことを保証する。
    • 例: ある人物がアイデンティティXでアップロードを行い、別名Yでレビューを行ったとすると、プラットフォームはこれらが同一人物であることを理解し、レビューに対する要求を満たしているとは見なさない。
  • [理解の上でのレビュー] レビュアーは、何を承認しようとしているのかをよく理解した上での決断を行うことができ、またそれを手助けされている。 レビュアーには、提案されたリビジョンと前にレビュー済みのリビジョンとの間の、完全な、意味のある内容のdiffが示されるべきである。 例えば、内容を表示せずに変更されたファイルのみを示すことは十分ではない。
  • [コンテキスト固有の承認] 承認はgitでのリポジトリ+ブランチのように、特定のコンテキストのためのものである。 完全にレビューされた内容をあるコンテキストから他に移すことには、依然としてレビューを要する。 (「コンテキスト」の正確な定義はプロジェクトに依存しており、これは、リリースブランチを切るといったような、広く理解された自動もしくはレビューなしのマージを妨げるものではない。)
    • Gitの例: あるリポジトリでの完全にレビューされたコミットが異なるリポジトリにマージされる場合や、あるブランチでのコミットが異なるブランチにマージされる場合、そのマージには依然としてレビューを要する。

ビルドの要求事項

ビルドプロセスに対する要求事項:

要求事項説明L1L2L3L4
スクリプト化されたビルド(Scripted build)

全てのビルドのステップは何らかの「ビルドスクリプト」で完全に定義されている。 唯一の手動のコマンドは、もしあるとしたら、ビルドスクリプトを起動するものである。

例:

  • ビルドスクリプトは Makefile であり、 make all で起動される。
  • ビルドスクリプトは .github/workflows/build.yaml であり、GitHub Actionsで起動される。
ビルドサービス(Build service)

全てのビルドステップは、開発者のワークステーション上ではなく、何らかのビルドサービスを使用して動作する。

例: GitHub Actions、Google Cloud Build、Travis CI。

コードとしてのビルド(Build as code)

ビルドサービスによって実行されるビルドの定義と設定は、バージョン管理システムに保管されたテキストファイルでの定義から、検証可能な形で導出されている。

検証可能な形で導出するとは、信頼されたチャネルを通じて直接取得されているか、導出された定義が、元のバージョン管理にリンクされる、信頼できる来歴の連鎖を持っていることを意味する。

例:

  • gitに保管された .github/workflows/build.yaml
  • SLSAに準拠したビルドプロセスでテキストファイルから生成され、SLSAの来歴メタデータが利用可能なOCIレジストリに保管されたTektonバンドル
その場限りの環境(Ephemeral environment)

ビルドサービスは、ビルドステップが、今回のビルドのためだけに提供され、過去のビルドから再利用されていないコンテナやVMのようなその場限りの環境で動作することを保証している。

隔離されている(Isolated)

ビルドサービスは、ビルドステップが、過去か現在かに関係なく他のビルド実行からの影響を受けない、隔離された環境で動作することを保証している。

  • ビルドは、来歴に対する署名キーのような、ビルドサービスのいかなる機密情報にもアクセスできてはならない(MUST NOT)
  • 動作時間が重なっている2つのビルドが、互いに影響を与えることができてはならない(MUST NOT)
  • あるビルドが残留したり、後続のビルドのビルド環境に影響を与えることができてはならない(MUST NOT)
  • ビルドキャッシュが使われている場合、改ざんを防ぐため、純粋に content-addressable でなければならない(MUST)
パラメーターレス(Parameterless)

ビルドの出力が、ビルドのエントリーポイントとトップレベルのソースの場所以外のユーザー・パラメーターに影響されることがない。 言い換えれば、ビルドはビルドスクリプトによって完全に定義されており、他の何物にもよらない。

例:

  • GitHub Actions workflow_dispatchinputs は空でなければならない(MUST)
  • Google Cloud Build user-defined substitutions は空でなければならない(MUST)。(サーバーによって値が定義されるようなデフォルトの置換は許容される。)
密封されている(Hermetic)

全ての推移的なビルドステップ、ソース、依存関係は全て不変の参照によって前もって宣言されており、それらのビルドステップはネットワークアクセスなしで動作する。

ユーザー定義のビルドスクリプトは、

  • ビルドサービスが理解できる形式の不変の参照を使用して、ソースと他のビルドステップを含む全ての依存関係を宣言しなければならない(MUST)

ビルドサービスは、

  • 全てのアーティファクトを信頼されたコントロール・プレーンで取得しなければならない(MUST)
  • 可変の参照(mutable references)を許可してはならない(MUST NOT)
  • 各アーティファクトの完全性を検証しなければならない(MUST)
    • もし 不変の参照が暗号学的ハッシュを含むなら、サービスはそのハッシュを検証し、検証が失敗した場合は取得を拒否しなければならない(MUST)
    • そうでない場合、サービスは、TLSやコード署名のような転送の完全性を保証しているチャネルを介してアーティファクトを取得しなければならない(MUST)
  • ビルドステップの実行中のネットワーク・アクセスを防止しなければならない(MUST)
    • この要求は「ベスト・エフォート」である。分別のあるチームが密封されていないビルドを行うことは抑止 すべき(SHOULD) ではあるが、何が何でも悪事を働こうとする者まで止める必要はない。例えば、コンテナを利用してネットワーク・アクセスを防止することでも十分である。
再現可能(Reproducible)

同一の入力アーティファクトでビルドステップを再実行すると、ビット対ビットの比較で同一の出力結果となる。 これを満たさないビルドは、なぜビルドが再現可能にならないのかの正当化の根拠を提供しなければならない(MUST)

“○” は、この要求が「ベスト・エフォート」であることを意味する。 ユーザーが提供したビルドスクリプトは、ビルドが再現可能であることを意図しているのか、もしくは何故そうではないかを正当化する根拠かの、いずれかを宣言すべきである(SHOULD)。 ビルドサービスは、再現可能であることを検証することなくこの意図を伝播してもよい(MAY)。 利用者は、ビルドが再現できない場合はそのビルドを拒否してもよい(MAY)

来歴の要求事項

来歴を生成・利用するプロセスに対する要求事項:

要求事項説明L1L2L3L4
利用可能(Available)

利用者が、利用者が受容する形式で来歴を利用可能である。 その形式は in-toto SLSA Provenance であるべき(SHOULD) だが、作成者と利用者の双方が合意しており、他の全ての要求事項を満たしているのであれば、別の形式を使用してもよい(MAY)

認証されている(Authenticated)

来歴の信憑性と完全性が利用者によって検証できる。 これは、来歴を生成するサービスだけがアクセス可能な秘密鍵によるデジタル署名を利用して行われるべきである(SHOULD)

サービスにより生成されている(Service generated)

来歴の中のデータはビルドサービスから取得されなければならない(MUST)(生成者 ビルドサービス である ためか、来歴の生成者がビルドサービスからデータを直接読んでいるためかのいずれか)。

サービスの一般ユーザーは、下記に記載のもの以外のコンテンツを注入したり改変したりできてはならない(MUST NOT)

以下の来歴フィールドは、ユーザーが制御するビルドステップで生成されてもよい(MAY)

  • アーティファクトを識別するによる出力アーティファクトのハッシュ。
    • 正当化の根拠: これで許してしまうのは、「悪い」ビルドが「良い」アーティファクトを生み出したことを不正に主張することだけである。 利用者は「良い」ビルドのみを受け入れ、「悪い」ビルドは拒否**しなければならない(MUST)**ため、これはセキュリティの問題にはならない。
  • 再現可能かどうかの真偽値と、再現可能による正当化理由。
偽造不可能(Non-falsifiable)

来歴はビルドサービスのユーザーが偽造できない。

注: この要求事項はサービスにより生成されているのより厳格なバージョンである。

  • 来歴の偽造不可能な性質を証明するのに使用されるあらゆる秘密要素(例えばデジタル署名を生成するのに使用される署名鍵)は、そのような要素に適した、ビルドサービスのアカウントからのみアクセス可能なシークレット管理システムに保管しなければならない(MUST)
  • そのような秘密要素はユーザー定義のビルドステップを実行している環境からアクセス可能であってはならない(MUST NOT)
  • 来歴の各フィールドは、信頼されたコントロール・プレーンにあるビルドサービスによって生成または検証されなければならない(MUST)。ユーザーが制御するビルドステップは、下記に記載のもの以外のコンテンツを注入したり改変したりできてはならない(MUST NOT)

以下の来歴フィールドは、ユーザーが制御するビルドステップによって、ビルドサービスが正しさを検証することなしに生成されてもよい(MAY)

  • アーティファクトを識別するを元にした出力アーティファクトのハッシュ。
    • 背景にある理由: これは、「悪い」ビルドが「良い」アーティファクトを作成したと不正に主張することを許すだけである。 これはセキュリティの問題ではない。なぜなら、利用者が「良い」ビルドのみを受け入れ、「悪い」ビルドを拒否しなければならない(MUST) ためである。
  • 「再現可能である」ことを意図しているかの真偽値と、再現可能からの正当化理由。
依存関係の完備(Dependencies complete)

来歴は、ビルドステップを実行している間に利用可能な全てのビルド依存関係を記録している。 これは、マシン、VM、ビルドワーカーのコンテナの初期状態を含む。

  • 全てのユーザー指定のビルドステップ、ソース、依存関係を含まなければならない(MUST)
  • 全てのサービス提供のアーティファクトを含むべきである(SHOULD)

来歴の内容に対する要求事項:

要求事項説明L1L2L3L4
アーティファクトを識別する(Identifies artifact)

来歴は、少なくとも1つの暗号学的ハッシュを介して出力アーティファクトを識別しなければならない(MUST)。 来歴は、異なるアルゴリズムを使用した、複数の識別のための暗号学的ハッシュを提供してもよい(MAY)。 1つのハッシュのみが提供されている場合、システム間の互換性のため、推奨される(RECOMMENDED) アルゴリズムはSHA-256である。 別のアルゴリズムが使用される場合、そのアルゴリズムは衝突攻撃と第二原像攻撃に対して耐性を持つべきである(SHOULD)

ビルド者を識別する(Identifies builder)

来歴は、ビルドを行い来歴を生成した主体を識別する。これは利用者が信頼しなければならない主体を表す。 例: 「GitHubにホストされたワーカーによるGitHub Action」「jdoe@example.comのマシン」

ビルド手順を識別する(Identifies build instructions)

来歴は、ビルドを実行するのに使用されたトップレベルの手順を識別する。

識別された手順は、ビルドから利用可能な最上位のレベルに位置しているべきである(SHOULD)(例えば、ビルドが build.sh を実行するよう指示された場合、リストアップするべきなのは build.sh であり、build.sh 内の個別の手順ではない)。

コードとしてのビルドが使用されている場合、これはソースリポジトリと、ビルド設定のエントリーポイントとなるべきである(SHOULD)the GitHub Actions exampleにある通り)。

ビルドがコードで定義されていない場合、何をするように依頼されたかの詳細をリストアップしてもよい(MAY)the Google Cloud Build RPC examplethe Explicitly Run Commands exampleにある通り)。

ソースコードを識別する(Identifies source code)

来歴は、ビルドで使用されたソースコードのリポジトリのオリジンを識別する。

識別されたリポジトリは、ビルドで直接使用されたソースのみを含むべきである(SHOULD)。 依存関係のソースを含むべきではない(SHOULD NOT)

レベル2では、この情報はユーザー由来のものでよい(MAY)。ビルド者によって認証されている必要はない(DOES NOT need)

レベル3以上では、この情報はビルド者によって認証されていなければならない(MUST) (別の言い方をすれば、ビルド者は自分自身でソースを取得しているか、取得を 監視している 必要がある)。

レベル4では、この情報は完全でなければならない(MUST) (別の言い方をすれば、ビルドで使用された全てのソースリポジトリがリストアップされている)。

✓ (Authenticated)✓ (Complete)
エントリーポイントを識別する(Identifies entry point)

来歴は、ビルドを駆動するのに使用された、設定の読み込み元がどのソースリポジトリであるかを含んだビルド定義(コードとしてのビルドを参照)の「エントリーポイント」を識別する。

例:

  • ソースリポジトリ: git URL + ブランチ/タグ/ref + コミットID
  • エントリーポイント: 設定ファイルへのパス(例えば ./.zuul.yaml)+ 設定内でのジョブ名(例えば envoy-build-arm64)
全てのビルド・パラメーターを含む(Includes all build parameters)

来歴は、ユーザーの制御下にある全てのビルド・パラメーターを含んでいる。 詳細はパラメーターレスを参照。 (L3では、それらのパラメーターはリストアップされなければならない。L4では、それらのパラメーターは空でなければならない)

全ての推移的な依存関係を含む(Includes all transitive dependencies)

来歴は、依存関係の完備でリストアップされた全ての推移的な依存関係を含んでいる。

再現可能性の情報を含む(Includes reproducible info)

来歴は、ビルドが再現可能であることが意図されているかどうかを示す真偽値を含んでいる。 また、もし再現可能であることを意図されていた場合は、ビルドを再現するために必要な全ての情報を含んでいる。 詳細は再現可能を参照。

メタデータを含む(Includes metadata)

来歴は、デバッグと調査を支援するためのメタデータを含んでいる。 これには少なくとも、開始と終了のタイムスタンプと、詳細なデバッグ・ログを見つけられるような一意な識別子を含んでいるべきである(SHOULD)

“○” = 推奨(RECOMMENDED)

共通の要求事項

サプライチェーンに関連するあらゆる信頼されたシステム(ソース、ビルド、配布、など)のための共通の要求事項。

要求事項説明L1L2L3L4
セキュリティ(Security)

システムは、侵害を防ぐためのTBDのベースライン・セキュリティ基準を満たしている。 (パッチ当て、脆弱性スキャン、ユーザーの隔離、転送中のセキュリティ、セキュアブート、マシンのアイデンティティ、など。 おそらくNIST 800-53かそのサブセット。)

アクセス(Access)

全ての物理的あるいはリモートでのアクセスは稀であり、ログ記録され、複数の関係者による承認の下での入退管理がされていなければならない。

スーパーユーザー(Superusers)

少数のプラットフォーム管理者のみは、ここにリストアップされた保証を覆すことができてもよい。 そうする場合は、別のプラットフォーム管理者による承認を必須としなければならない(MUST)