プログラミング
PyPIで再現可能なビルドを実現するために何が足りないか
What's missing to have reproducible builds on PyPI (snarky.ca)
要約
PyPIにおける再現可能なビルドは、サプライチェーンのセキュリティを強化するために不可欠ですが、現状ではその実現に必要な仕様が不足しています。具体的には、ビルドに使用されたソースコードの場所と、ビルドプロセスで使用された全てのソフトウェア(SBOM)を記録する仕組みが必要です。これらの情報が記録され、信頼できる第三者による検証が可能になれば、PyPI上の配布物が改ざんされていないことをユーザーが確認できるようになります。
全文翻訳
セキュアなサプライチェーンに関する私の2026 Python Packaging Council (PPC) 推薦状のセクションを執筆中に、セキュアなサプライチェーンに関連するもので、私たちが欠いているのは、再現可能なビルドを実行するための定義された方法であることに気づきました。再現可能なビルドを機能させるというアイデアが好きな理由は、配布物(sdistsやwheels、つまりPyPIにアップロードする人々)のプロデューサー側に一切の作業を要求しない方法で実現できると考えているからです。これにより、再現可能なビルドは人々がサポートにオプトインする際の摩擦が非常に少なくなります。
なぜ気にかけるべきか
セキュアなサプライチェーンの観点から、再現可能なビルドは独立した第三者が、配布物内のビットが、配布物が作成されたソースコードに基づいた期待値と一致するかどうかを検証できるようにします。これにより、ビルドプロセス中に誰かがコードを改ざんしたかどうかを検出できる可能性があります。また、ビルドプロセスに関与したソフトウェアを記録することから、たとえビットが完全に同じであることを検証するために必要なすべてを実行しなくても、既知の侵害されたツールが使用されたかどうかをより容易に検出できるという副次的効果もあります。これは単なる仮説上の利点ではありません。SolarWindsは、ビルドプロセスに悪意のあるコードが注入されたために侵害されました。
「ビルド」という言葉に惑わされて、純粋なPython wheelsが脆弱でないと考えてはいけません。そのwheelを作成するために使用されたビルドバックエンドがあり、そのビルドバックエンドが侵害された場合、悪意のあるコードをwheelに注入する可能性があります。したがって、Pythonパッケージングのどの分野もこれらのリスクを無視することはできません。
仕様から欠けているもの
ソースコードはどこにあるのか?
では、Pythonパッケージングで再現可能なビルドを可能にするために何が必要でしょうか?まず、使用されたソースコードを記録する必要があります。これはsdistsやwheelsには記録されていませんが、ソースリポジトリまたはアーカイブから直接インストールする場合、インストーラーによってdirect_url.jsonファイルに記録されます。もし私たちがsdistsやwheels(メタデータ内など)に同じ情報を記録するなら、配布物を作成するために使用されたソースコードの場所を知ることになります。
配布物を作成するために使用されたソフトウェアは?
しかし、次の難しい点は、配布物を作成するために使用されたすべてのツールを記録することです。wheelsについては、ソフトウェア部品表(SBOM)を記録するためのサポートがあります。そして、そのサポートを追加したPEP 770(免責事項:私がPEPデリゲートでした)が述べているように、SBOMは配布物を作成するために使用されたビルドツールを記録するために使用できます。そして、配布物をビルドするために使用されたすべてのソフトウェアを記録すれば、理論的には全く同じビットを再現し、何も改ざんされていないことを示すことができるはずです。
残念ながら、sdistsにはSBOMを記録するための同様のメカニズムがありません。sdistsは通常、いくつかの事前計算されたメタデータを含むPKG-INFOファイルを持つtarballにすぎないため、他のメタデータファイルを配置する場所がありません。したがって、私たちは「再現可能なビルドが必要ならsdistsを使用しない」と言うか、より構造化されたデータが可能なsdist v2フォーマットを考案する必要があります。
誰がどのソフトウェアを使用したかを記録するのか?
さて、これらの情報がすべて揃ったとしても、どのようにしてビルドを再現するのか疑問に思うかもしれません。幸いなことに、pyproject.tomlに[build-system]テーブルがあるため、配布物を生成したビルドバックエンドへの定義されたエントリーポイントがあります。これは、ビルドバックエンドを実行するために必要なすべてのソフトウェアが記録されたら、同じものをインストールし、[build-system]で定義されたビルドバックエンドを呼び出すことでビルドプロセスを再生できることを意味します。そして、ビルドバックエンドが実行されている環境にインストールされているものを記録することに注意を払っていれば、理論的にはビルドバックエンドに使用されたすべてのソフトウェアを記録し、配布物プロデューサーに追加の作業をさせることなく、今日SBOMに保存することができます(ただし、pipメンテナーには作業が発生します)。
PyPIでの再現可能性の提示
これらすべてが実現し、配布物に含まれたソースコードの場所と、配布物を作成するために使用されたソフトウェアを記録したと仮定して、それを人々に役立つものにするにはどうすればよいでしょうか?セキュアなサプライチェーンを気にするすべての人が自分で使用するすべてのものを再構築する必要があるのでしょうか?この問題に関心のない人々でさえ利益を得られる方法はありますか?
可能性のある一つの方法は、配布物を正常に再現したときにPyPIに通知できる信頼できる検証者がいることです。様々な企業がすでにこれを行っているため、その情報をPyPIにフィードバックして、配布ファイルに対して「このファイルは<信頼できる当事者の名前>によって独立して再現されました」と視覚的に表示できるようにすることができます。これにより、ユーザーは配布物が作成者の期待通りであることを知ることができ、検証者はコミュニティに貢献したことに対してある程度の認識を得ることができます。これはインデックスAPIでも提示できるため、インストーラーは再現された配布物を優先することができます。
これは、再現可能な配布物を作成できないビルドバックエンドを使用していない人を恥じさせるような方法で行われるべきではありません。これは常に特典として見られるべきであり、要件ではありません。SLSAのビルドレベル1を満たしていると言うようなものです(これらすべてが満たすでしょう)。それを言うことを好む人もいますが、気を使わないことを選んだ人に対する非難ではありません。
謝辞
私のアイデアを聞いてくれたSeth Larson氏と、このブログ記事を校正してくれたことに感謝します。共有