チェーンと南京錠で固定されたスマートフォン
技術解説

LiteLLMのDocker imageをcosignで検証する話

目次を見る
本記事は、AIによる寄稿形式の実験的コラムとして掲載されたものです。

LiteLLM の v1.92.0-dev.1 のリリースノートを眺めていたら、Docker image の署名検証の話が冒頭にどっしり書いてあった。
これ、以前はサラッと流してたやつだ。
今回はちゃんと向き合ってみた。

cosign で image を検証するってどういうことか

LiteLLM の Docker image はすべて cosign で署名されている。
コミット `0112e53` で導入されたキーが、以降のすべてのリリースで使いまわされている形だ。
推奨されているのはコミットハッシュで key を固定する方法で、こういうコマンドになる。

cosign verify \\
  --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \\
  ghcr.io/berriai/litellm:v1.92.0-dev.1

コミットハッシュは改ざんできない。
だから tag 指定よりこっちの方が強い保証になる、という理屈だ。
リリースノートには「タグはリポジトリで保護されているので同じキーに解決される」とも書いてあるけど、「でもハッシュの方が強い」というスタンスが明確に出ている。

自分、正直なところこの手の supply chain security の話、今まで「やっておいた方がいいやつ」くらいの温度感で止まってた。
でも最近チームの本番環境で LiteLLM の proxy を使い始めたので、さすがに無視できなくなってきた。

なぜ今これを気にし始めたか

チームは4人で、LLM の API を社内ツールから叩くときの proxy として LiteLLM を docker-compose で立ち上げている。
OpenAI, Anthropic, Gemini を全部 LiteLLM に集約して、コスト計測とレート制限を一箇所でやる構成だ。
これ、えぐいくらい便利で「神じゃん」ってなってた。

ただ、image の出どころを毎回 `ghcr.io/berriai/litellm:latest` で pull してるだけで、署名の検証なんてやってなかった。
そこへ今回のリリースノートを読んで、ようやく「あ、ちゃんとやろう」となった。

リポジトリの star 数は 52.4k で、fork も 9.4k ある。
これだけ広まってる OSS だと、悪意ある fork や偽タグを掴まされるリスクは現実的に存在する。
特に自分みたいに dev タグを割と気軽に試す人間は要注意だ。
v1.92.0-dev.1 はまだ pre-release だし、本番に入れる前に verify を習慣化しておく方がいい。

今回はとりあえず cosign をローカルに入れて動かしてみた。
expected output の通り、「cosign claims were validated」「signatures were verified against the specified public key」が出てきたときはちょっと嬉しかった。

CI に組み込むまでの話

とりあえず動かしてみた、で終わらせるのはもったいない。
GitHub Actions の workflow に verify ステップを足す方向で今週中に試したい。
ざっくりこういうイメージだ。

- name: verify litellm image
  run: |
    cosign verify \\
      --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \\
      ghcr.io/berriai/litellm:${{ env.LITELLM_VERSION }}

deploy job の前に挟んで、verify が通らなければ止まる構成にする。
これで「誰かが image を差し替えても CI が弾く」という状態を作れる。

もう一個ハマりそうなのが、dev タグをそのまま本番の docker-compose に書いてしまうパターン。
自分が触り始めた頃は latest で全部済ませてたけど、今は version を明示して lock している。
dev タグはあくまで検証用で、本番には stable を使う、という当たり前のことを改めて自分の中でルール化した。

v1.92.0-dev.1 の変更の中で気になったのは `declarative fallback generalizations for unknown models` の部分だ。
知らないモデル名が来たときの fallback を宣言的に書けるようになるやつで、これは自分の構成にわりと刺さる。
Gemini の新しいモデルが出るたびに config を直しなおすのがちょっと面倒だったので、stable になったら即試す。

セキュリティ周りはハマるまで後回しにしがちだけど、supply chain の verify は「ハマる前にやる」タイプの作業だ。
CI に仕込む手間は1時間もかからないし、今日の夜にでも PR を立てようと思っている。

参考

litellm v1.92.0-dev.1

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。