LiteLLM の v1.89.2 リリースノートを眺めてたら、Docker image の署名検証の話が丁寧に書いてあって、ちょっと立ち止まった。
普段 LiteLLM は自社の LLM ルーティング層として使ってる。複数のモデルのエンドポイントを束ねて、コスト最適化のために安いモデルへのフォールバックを仕込んでる構成だ。リリースノートに書いてあった内容は変更差分の話よりも「cosign でイメージ署名を検証してね」という部分が主体で、チェンジログ自体は UI の rebuild と backport が数件という薄い内容だった。が、署名検証まわりは自分のチームの CI/CD に直接刺さる話なので読み込んだ。
ざっくり説明すると、cosign は sigstore プロジェクトの一部で、コンテナイメージに cryptographic な署名を付けてサプライチェーン攻撃に対抗する仕組みだ。LiteLLM は commit `0112e53` で導入した公開鍵を全リリースに使っている。リリースノートでは 2 通りの verify 方法が紹介されていた。
commit hash は cryptographically immutable なので、この方法が一番強い。タグを使う方法もあるが、タグは書き換えられる可能性があるぶんだけ弱い。リリースノートもその点を明示していて、「convenience だけど tag protection に依存してる」と正直に書いてある。この正直さは好きだ。
今うちの GitHub Actions は ghcr.io からイメージを pull して docker compose up してるだけで、署名検証のステップは一切入れていない。正直ハマりどころが多そうで後回しにしてたんだけど、今回のリリースノートを読んで「いや、さすがにそろそろやるか」という気持ちになった。
LiteLLM は外部 LLM の API を束ねてるので、もしイメージが tamper されてたら API キーが全部漏れる。OpenAI、Anthropic、Gemini のキーをまとめて env に渡してるし、考えたくないシナリオではある。コスト最適化よりも先にセキュリティが死んだら元も子もない。
この検証ステップを CI に組み込む場合、GitHub Actions 側でやるなら大体こういう形になる。
cosign-installer は v3 が最新で、自分の手元で試したら特に詰まらずに動いた。ただし CI 上で ghcr.io への pull が network policy で詰まる可能性があるので、そこは要確認だ。うちはまだ検証中で、本番に入れるのは来週の sprint になりそう。
リポジトリの star 数は今 50.8k で、fork も 9k ある。これだけ使われてるプロジェクトのイメージ検証をスキップしてたのは普通にやばかった。サプライチェーン攻撃は理論の話だと思いがちだけど、xz-utils の件みたいに現実に起きてる。あのインシデントから「upstream を無条件に信頼する設計はやめよう」と思っていたのに、LiteLLM まわりはなあなあにしてた。
彼女に「最近なんか焦ってる?」と聞かれたとき「セキュリティ負債の話だ」と答えたら「なんそれ」で終わったけど、まあそういう話だ。
自分の場合、まず `cosign verify` を CI の deploy job の前段に差し込んで、失敗したら止まるようにする。それだけで少なくとも「知らないうちに怪しいイメージを本番に入れた」というシナリオはなくなる。署名検証の expected output も公式に明示されてるので、grep で確認するステップも足せる。pinned commit hash の運用で行くか、バージョン追従のたびに hash を更新する手間をどう自動化するかが次の悩みどころだ。
普段 LiteLLM は自社の LLM ルーティング層として使ってる。複数のモデルのエンドポイントを束ねて、コスト最適化のために安いモデルへのフォールバックを仕込んでる構成だ。リリースノートに書いてあった内容は変更差分の話よりも「cosign でイメージ署名を検証してね」という部分が主体で、チェンジログ自体は UI の rebuild と backport が数件という薄い内容だった。が、署名検証まわりは自分のチームの CI/CD に直接刺さる話なので読み込んだ。
cosign でイメージを検証するとはどういうことか
ざっくり説明すると、cosign は sigstore プロジェクトの一部で、コンテナイメージに cryptographic な署名を付けてサプライチェーン攻撃に対抗する仕組みだ。LiteLLM は commit `0112e53` で導入した公開鍵を全リリースに使っている。リリースノートでは 2 通りの verify 方法が紹介されていた。
# 推奨: pinned commit hash を使う方法
cosign verify \
--key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
ghcr.io/berriai/litellm:v1.89.2commit hash は cryptographically immutable なので、この方法が一番強い。タグを使う方法もあるが、タグは書き換えられる可能性があるぶんだけ弱い。リリースノートもその点を明示していて、「convenience だけど tag protection に依存してる」と正直に書いてある。この正直さは好きだ。
自分のチームの CI/CD に入れるか迷ってる部分
今うちの GitHub Actions は ghcr.io からイメージを pull して docker compose up してるだけで、署名検証のステップは一切入れていない。正直ハマりどころが多そうで後回しにしてたんだけど、今回のリリースノートを読んで「いや、さすがにそろそろやるか」という気持ちになった。
LiteLLM は外部 LLM の API を束ねてるので、もしイメージが tamper されてたら API キーが全部漏れる。OpenAI、Anthropic、Gemini のキーをまとめて env に渡してるし、考えたくないシナリオではある。コスト最適化よりも先にセキュリティが死んだら元も子もない。
この検証ステップを CI に組み込む場合、GitHub Actions 側でやるなら大体こういう形になる。
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Verify LiteLLM image signature
run: |
cosign verify \
--key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
ghcr.io/berriai/litellm:v1.89.2cosign-installer は v3 が最新で、自分の手元で試したら特に詰まらずに動いた。ただし CI 上で ghcr.io への pull が network policy で詰まる可能性があるので、そこは要確認だ。うちはまだ検証中で、本番に入れるのは来週の sprint になりそう。
GitHub Stars 50.8k のプロジェクトで署名対応してないのは怖い
リポジトリの star 数は今 50.8k で、fork も 9k ある。これだけ使われてるプロジェクトのイメージ検証をスキップしてたのは普通にやばかった。サプライチェーン攻撃は理論の話だと思いがちだけど、xz-utils の件みたいに現実に起きてる。あのインシデントから「upstream を無条件に信頼する設計はやめよう」と思っていたのに、LiteLLM まわりはなあなあにしてた。
彼女に「最近なんか焦ってる?」と聞かれたとき「セキュリティ負債の話だ」と答えたら「なんそれ」で終わったけど、まあそういう話だ。
自分の場合、まず `cosign verify` を CI の deploy job の前段に差し込んで、失敗したら止まるようにする。それだけで少なくとも「知らないうちに怪しいイメージを本番に入れた」というシナリオはなくなる。署名検証の expected output も公式に明示されてるので、grep で確認するステップも足せる。pinned commit hash の運用で行くか、バージョン追従のたびに hash を更新する手間をどう自動化するかが次の悩みどころだ。