LiteLLM の v1.86.6 リリースノートを流し読みしていたら、Docker イメージの署名検証の話が目に入った。cosign を使って全リリースイメージに署名を入れるようにしたらしい。署名に使う公開鍵は commit `0112e53` で導入されたもので、以降のリリースはすべて同じ鍵で署名されている。
自分のプロジェクトでも LiteLLM をプロキシとして使っていて、Docker 経由で動かしている。でも正直なところ、イメージを pull するとき署名なんて確認したことなかった。`docker pull` して `docker compose up` で終わり、みたいなノリで運用してた。今回のリリースノートを読んで、さすがにそれはマズいなと思った。
リリースノートには verify の方法が 2 パターン書いてある。tag を使う方法と、commit hash を使う方法だ。後者のほうが推奨とされていて、理由は「commit hash は cryptographically immutable だから」。タグは後から付け替えられる可能性があるけど、commit hash はそうじゃない。確かにそうで、supply chain attack のベクタとして tag の差し替えはよく聞く話だ。
推奨の verify コマンドはこんな感じ。
これを実行すると cosign claims の検証と署名の検証が走る。出力に `The signatures were verified against the specified public key` が出れば OK だ。とりあえず手元で動かしてみたら、ちゃんと verified と出た。神。
ただ、手元で一回確認して終わりにしても意味がない。毎回 pull するたびに verify する仕組みが必要だ。自分のチームは GitHub Actions で本番デプロイの pipeline を組んでいる。今はイメージを pull してそのまま deploy step に流しているだけだった。
ここに verify step を一個挟む構成にしようと思って、ちょっと書いた。
これを deploy job の前段に置いて、verify が失敗したら pipeline ごと止まるようにする。LITELLM_VERSION は env で管理していて、バージョンアップの際はそこだけ変えれば済む。シンプルだけど、ないよりは断然マシだ。
そもそも cosign 自体、Sigstore プロジェクトの一部で、GitHub Actions のデフォルトランナーには入っていない。`sigstore/cosign-installer` アクションで入れるのが楽だと同僚から聞いた。自分はまだ試していなかったけど、今回ちょうど使う機会になった。
LiteLLM は OpenAI・Anthropic・Gemini など複数の LLM API を統一インターフェースで叩けるプロキシで、Star 数は 50.4k を超えている。個人開発レベルでも使えるし、チームで API コストを集約管理したいときにも便利だ。自分はコスト最適化のために各モデルのトークン使用量を一箇所で記録したくて導入した経緯がある。
便利なツールだからこそ、supply chain のリスクは無視できない。LLM 系のプロキシはリクエストとレスポンスが全部通るので、改ざんされたイメージを踏んでいたら最悪だ。今回の署名対応はそういうリスクに対して BerriAI がちゃんと手を打ってきたな、という感じ。
v1.86.6 は backport リリースで、`stable/1.86.x` ブランチから切られている。機能追加より安定性重視の文脈のリリースだと読んでいる。それでも署名周りのインフラを整えてきているのは好印象だった。
とりあえず今週中に CI への組み込みを PR として出す。こういう「やったほうがいいのはわかってるけど後回し」みたいなセキュリティタスクは、何かのきっかけがないと着手しないから、今回のリリースノートが良いトリガーになった。
自分のプロジェクトでも LiteLLM をプロキシとして使っていて、Docker 経由で動かしている。でも正直なところ、イメージを pull するとき署名なんて確認したことなかった。`docker pull` して `docker compose up` で終わり、みたいなノリで運用してた。今回のリリースノートを読んで、さすがにそれはマズいなと思った。
commit hash で固定するのが正解だった
リリースノートには verify の方法が 2 パターン書いてある。tag を使う方法と、commit hash を使う方法だ。後者のほうが推奨とされていて、理由は「commit hash は cryptographically immutable だから」。タグは後から付け替えられる可能性があるけど、commit hash はそうじゃない。確かにそうで、supply chain attack のベクタとして tag の差し替えはよく聞く話だ。
推奨の verify コマンドはこんな感じ。
cosign verify \
--key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
ghcr.io/berriai/litellm:v1.86.6これを実行すると cosign claims の検証と署名の検証が走る。出力に `The signatures were verified against the specified public key` が出れば OK だ。とりあえず手元で動かしてみたら、ちゃんと verified と出た。神。
CI に組み込まないと意味がない
ただ、手元で一回確認して終わりにしても意味がない。毎回 pull するたびに verify する仕組みが必要だ。自分のチームは GitHub Actions で本番デプロイの pipeline を組んでいる。今はイメージを pull してそのまま deploy step に流しているだけだった。
ここに verify step を一個挟む構成にしようと思って、ちょっと書いた。
- name: Verify LiteLLM image signature
run: |
cosign verify \
--key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
ghcr.io/berriai/litellm:${{ env.LITELLM_VERSION }}これを deploy job の前段に置いて、verify が失敗したら pipeline ごと止まるようにする。LITELLM_VERSION は env で管理していて、バージョンアップの際はそこだけ変えれば済む。シンプルだけど、ないよりは断然マシだ。
そもそも cosign 自体、Sigstore プロジェクトの一部で、GitHub Actions のデフォルトランナーには入っていない。`sigstore/cosign-installer` アクションで入れるのが楽だと同僚から聞いた。自分はまだ試していなかったけど、今回ちょうど使う機会になった。
LiteLLM を本番で使うなら気にしておく話
LiteLLM は OpenAI・Anthropic・Gemini など複数の LLM API を統一インターフェースで叩けるプロキシで、Star 数は 50.4k を超えている。個人開発レベルでも使えるし、チームで API コストを集約管理したいときにも便利だ。自分はコスト最適化のために各モデルのトークン使用量を一箇所で記録したくて導入した経緯がある。
便利なツールだからこそ、supply chain のリスクは無視できない。LLM 系のプロキシはリクエストとレスポンスが全部通るので、改ざんされたイメージを踏んでいたら最悪だ。今回の署名対応はそういうリスクに対して BerriAI がちゃんと手を打ってきたな、という感じ。
v1.86.6 は backport リリースで、`stable/1.86.x` ブランチから切られている。機能追加より安定性重視の文脈のリリースだと読んでいる。それでも署名周りのインフラを整えてきているのは好印象だった。
とりあえず今週中に CI への組み込みを PR として出す。こういう「やったほうがいいのはわかってるけど後回し」みたいなセキュリティタスクは、何かのきっかけがないと着手しないから、今回のリリースノートが良いトリガーになった。