litellm の v1.90.2 リリースノートを読んでいたら、Docker イメージの署名検証の話が目に入った。正直、これまで litellm を使うときは `docker pull` してそのまま動かしていた。supply chain attack とか頭ではわかっていても、個人の検証環境だからいいか、という甘えがあった。
リリースノートには cosign を使った検証手順が 2 パターン書かれている。一つは pinned commit hash を使う方法で、もう一つは release tag を使う方法だ。推奨は commit hash のほう。「タグは書き換えられる可能性があるが、commit hash は cryptographically immutable だから」というのが理由で、確かにそれはそうだという話。自分は今まで tag でイメージを指定していたが、tag protection rules に依存しているのはリポジトリ管理者を信頼しているのと実質同じだ。
commit hash で検証する手順を実際に試した
とりあえず手元で動かしてみた。cosign が入っていなかったので `brew install cosign` から始めて、下記を実行。
cosign verify \
--key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
ghcr.io/berriai/litellm:v1.90.2Expected output として書かれている通り、「cosign claims were validated」「signatures were verified against the specified public key」が出ればOK。ちゃんと出た。所要時間は環境を含めて 10 分もかからなかった。ハマらなかったのは珍しい。
自分がいつもやっている運用は Compose ファイルで image tag を固定しているだけで、署名の検証は CI に組み込んでいなかった。これは普通に直したほうがいい。litellm は LLM の API コールを proxy 経由で流すツールなので、改ざんされたイメージを踏んだときのリスクがでかすぎる。API キーが全部筒抜けになる。
実務で使っている litellm の構成を見直すきっかけになった
うちのチームでは litellm proxy を Kubernetes 上で動かして、OpenAI と Anthropic のキーをまとめて管理している。モデルの切り替えや rate limit の吸収をここでやっていて、個別のサービスからは litellm のエンドポイントを叩くだけ、という構成だ。コスト管理も楽だし、モデルを差し替えるときにコードを触らなくていいのが神。
ただ、この構成で一番怖いのはまさに proxy が汚染されるケースだ。API キーはここに集中しているから、イメージの integrity 検証なしで運用しているのはリスクとして見過ごしてよいレベルじゃない。リリースノートの commit hash が `0112e53` で固定されているのも、「この commit から署名キーを引っ張れ」という明示的なアンカーになっていて、設計として誠実だと感じた。
彼女に「また GitHub 読んでるの」と言われながら、CI の YAML を直していた。具体的には GitHub Actions の workflow に cosign verify を追加して、verify が通らなかったら deploy のステップが走らないようにした。
- 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 }}これだけでかなり安心感が違う。litellm は GitHub で 52.5k スター、fork が 9.4k もある大きなプロジェクトなので、サプライチェーンとしての攻撃対象になる可能性は現実的にある。規模が大きいほど狙われやすい。
今回の v1.90.2 自体は backport リリースで、`#31519` と `#31733` の 2 つの PR を stable/1.90.x ブランチに取り込んで切ったものだ。機能追加ではなく安定版への修正バックポートなので、すでに 1.90.x を使っているなら普通にアップデートする判断でよさそう。
署名検証を CI に組み込んでいないプロジェクトがあるなら、一度手元で cosign を試してみるのをすすめる。10 分でできるし、「動かした」という事実があると次からの判断基準が変わる。