binary cacheの公開鍵を追加することはbuilderを信頼することに近い
binary cacheに署名が付いていても、「署名されているから安全」という理解では不十分である。重要なのは、その署名鍵にどの権限を与えているかである。
Nixのsubstituteは「バイナリパッケージ」よりbuild resultに近い と Nixのstore pathは通常content-addressedではない のNixでは、この点が特に明確である。
Nixの公式ガイドは、custom binary cacheのpublic keyをtrusted-public-keysへ追加すると、対応するprivate keyで署名された任意のrequested store objectをNixが受け入れると警告している。private keyを持つ主体は、実行ファイルを含む任意のfileをstoreへsubstituteでき、場合によってはそれが高い権限で実行され得る。このため公式文書は「無条件に信頼できるpublic keyだけを追加する」よう明示している。
これはbinary cache signing keyが、単なるCDNのTLS証明書とは異なることを示す。cache operatorに対して、概念上は 「このstore pathに対応するbuild resultはこれである」と証言する権限 を与えることになる。
通常のNix store pathの多くがinput-addressedであることも、このtrustを必要にする理由である。pathだけからactual output bytesを自己検証できないため、外部storeから受け取ったobjectが本当にそのderivationの結果であることを署名者に委ねる。Nixのlocal storeはrequire-sigsをdefault trueとしており、外部からcopyするstore pathにtrusted signatureを要求する。
GNU Guixも同様に、substitute serverのpublic keyをauthorizeすることは、そのserverがcompromiseされずgenuine substitutesを返すことを信頼する行為だと明記している。Nix/Guixに共通するのは、binary cacheを単なる性能最適化層ではなくsupply-chain trust boundaryとして扱っている点である。
一方、content-addressed objectでは事情が変わる。Nixのstore pathは通常content-addressedではない の通り、期待するcontent addressが既知なら、取得したbytesから整合性を検証できるため、Nixはそのobject自体の受け入れに追加署名を必要としない場合がある。
しかしこれはcache operatorを完全にtrustしなくてよいという意味ではない。どのcontent addressを期待すべきかを別のmetadataから受け取るなら、そのmetadata側のtrustが残る。またcontent-addressed artifactが正しいsourceから正しいbuilderで作られたこともaddressだけでは分からない。この差は checksum・signature・provenanceは別の保証をする と content addressingはprovenanceではない に繋がる。
binary cacheのtrustを評価するときは、少なくとも次を分けて考える必要がある。
- cacheがartifact bytesを改竄できるか
- cache signing keyのholderが任意artifactを正当化できるか
- package/derivation metadataを誰が決めるか
- artifact identityがcontent-addressedかinput-addressedか
- key compromise時にrevocation/rotation/freshnessをどう扱うか
最後の問題は、署名自体が正しくても古いmetadataやartifactを再提示される 署名検証だけではrollback・freeze attackを防げない に繋がる。
出典
🔗 リンクされているノート
- ビルド済みパッケージ管理 調査ノート
- Bazel Remote Cacheはpackage binary cacheと同じ問題をaction粒度で扱う
- binary cacheとpackage repositoryは似ているが一次性が違う
- prebuiltがないときのsource build fallbackは同じ意味ではない
- content addressingはprovenanceではない
- lockfileで依存を固定してもreproducible buildにはならない
- 署名検証だけではrollback・freeze attackを防げない
- Nixのsubstituteは「バイナリパッケージ」よりbuild resultに近い
- ビルド済みパッケージ配布を一括りにしない