近年、国内外のエンタープライズ環境において、AIモデルのセキュリティに関する課題が顕在化しています。特に、「セキュリティツールを導入したのに、なぜか不安が拭えない」「監査は通ったが、本当にこれで攻撃を防げるのか?」といった懸念が多くの開発現場や経営層から共有されています。
皆さんの組織では、AIモデルのデプロイメントパイプラインに「コード署名(Code Signing)」や「モデル署名(Model Signing)」を導入していますか? もし「Yes」なら、素晴らしい第一歩です。しかし、もし「署名しているから安全だ」と確信しているなら、この記事はまさにあなたのためのものです。
実は、「署名済みのモデル」こそが、最も油断を生みやすい攻撃ベクトルになり得るというパラドックスが存在します。攻撃者は、正面玄関の頑丈な鍵(署名アルゴリズム)を真正面から壊そうとはしません。彼らは、鍵の受け渡し場所や、鍵をチェックするガードマンの隙(パイプラインの検証プロセス)を狙うのです。
今回は、あえて教科書的な「実装手順」ではなく、「署名システムを導入していたにもかかわらず、改ざんを許してしまった事例」に焦点を当てます。なぜ防御は突破されたのか? そのプロセス上の欠陥を解き明かし、MLOpsにおける真の堅牢性とは何かを一緒に考えていきましょう。技術の本質を見抜き、ビジネスを安全に加速させるための最短距離を探ります。
なぜ「署名済み」モデルが攻撃されたのか
AI/MLシステムにおけるセキュリティは、従来のソフトウェア開発(DevSecOps)とは異なる独自の課題を抱えています。コード署名は、ソフトウェアのサプライチェーン攻撃を防ぐための標準的な手段として確立されていますが、AIモデル(特にディープラーニングモデル)に適用する際には、いくつかの「死角」が生まれます。
MLOpsにおけるセキュリティの死角
通常のアプリケーションコードは、人間が読み書き可能なテキストファイルであり、Gitなどでバージョン管理され、レビュープロセスを経てビルドされます。一方、AIモデルの実体は、巨大なバイナリデータ(重みパラメータ)や、Pickle形式などでシリアライズされたオブジェクトです。
ここには2つの大きなリスクが存在します。
- ブラックボックス性: モデルファイルの中身を目視でレビューすることは不可能です。悪意あるコードが埋め込まれていても(例えば、特定の入力で誤動作するバックドアや、デシリアライズ時に任意のコードを実行するペイロードなど)、コードレビューでは発見できません。
- アーティファクトの巨大さと頻繁な更新: モデルは数GBのサイズになることが珍しくなく、再学習によって頻繁に更新されます。このため、従来の静的なマルウェアスキャンや署名プロセスがボトルネックとなり、現場の判断で「特例的なバイパス」が行われやすいのです。
本記事で扱う事例の定義
今回取り上げるのは、実際のインシデント傾向をベースに再構成したシナリオです。ここで想定する開発組織は、決してセキュリティ意識が低かったわけではありません。むしろ、GPG鍵による署名やハッシュ検証を導入し、CI/CDパイプライン上で自動化を行っていました。
それにもかかわらず、攻撃者はパイプラインの「継ぎ目」を巧みに突き、正規の署名が付与された「汚染モデル」を本番環境に送り込むことに成功しました。これは、ツール自体の欠陥ではなく、「信頼の連鎖(Chain of Trust)」の設計ミスに起因するものです。システム全体を俯瞰するアーキテクトの視点が欠けていたと言えるでしょう。
失敗事例:自動化パイプラインに潜む「認証の形骸化」
具体的な失敗のメカニズムを分析します。ここでは、セキュリティ対策を講じたつもりでも陥りやすい2つの代表的なアンチパターン、「鍵管理不備」と「検証不備」について詳述します。
ケースA:署名鍵管理の不備によるなりすまし
CI/CDパイプライン(JenkinsやKubernetes環境など)において、モデルの改ざんを防ぐためにコード署名を導入するケースは多いですが、その鍵管理に致命的な脆弱性が潜んでいることが珍しくありません。
【攻撃のメカニズム】
典型的な失敗は、署名に用いる秘密鍵をCI/CDツールの環境変数として静的に保存してしまう構成です。攻撃者がプラグインの脆弱性などを突いてCI環境に侵入した場合、この秘密鍵は容易に奪取可能です。
攻撃者は盗み出した正規の秘密鍵を使用し、バックドア(特定の顧客データを外部送信するコードなど)を仕込んだ不正なモデルに対して署名を行います。推論サーバー側の検証ロジックが「署名の整合性」のみをチェックし、「署名者のアイデンティティ(誰が)」や「署名コンテキスト(いつ、どのパイプラインで)」を検証していない場合、システムはこれを正規のモデルとして受け入れてしまいます。
結果として、「正規の署名がある=安全」という誤った前提のもと、汚染されたモデルが本番環境へデプロイされる事態を招きます。
ケースB:検証プロセスのバイパスとデシリアライズ攻撃
GitHub Actionsなどのワークフローエンジンを利用してモデルのハッシュ値を照合する場合でも、検証スクリプトのロジック自体に脆弱性があれば防御は機能しません。
【攻撃のメカニズム】
以下のような単純な検証フローには、重大な欠陥があります。
- ストレージ(S3等)からモデルをダウンロード
- 署名ファイルをダウンロード
- 署名を検証
- 検証OKならモデルをロード(
pickle.load()等)
このフローでは、「署名検証の完了後、モデルロードの直前」というわずかなタイムラグを狙った「TOCTOU(Time-of-Check to Time-of-Use)」攻撃が成立するリスクがあります。攻撃者がストレージへの書き込み権限を(フィッシング等で)得ていた場合、検証通過直後にファイルを差し替えることで、不正なモデルを読み込ませることが可能です。
さらに、検証スクリプトのエラーハンドリングにおいて、タイムアウトや検証エラー時に処理を停止せず「Warning」ログのみで続行する「Fail Open」の設定になっているケースも散見されます。攻撃者は意図的に検証サーバーに負荷をかけて検証をスキップさせ、任意のコード実行(RCE)につながるデシリアライズ攻撃を成功させることができます。
被害の影響範囲とビジネス損失
これらのアンチパターンが引き起こす被害は、単なる推論精度の低下にとどまりません。経営リスクに直結する重大な事態を招きます。
- 機密情報の流出: モデルが処理する入力データ(PIIなど)が外部へ送信されるリスク。
- システムの乗っ取り: 推論サーバーを踏み台として、社内ネットワーク深部への侵入を許すリスク。
- 信頼の失墜: 「安全なAI」を謳うサービスの根幹が揺らぎ、ブランド毀損に直結します。
最も厄介なのは、「署名済みである」という事実が、インシデント発生時の原因究明を妨げるバイアスとなる点です。「署名は正しいはずだ」という思い込みが、調査の目を曇らせ、対応を遅らせる要因となります。経営者視点とエンジニア視点の両方から、この「思い込みの罠」を警戒する必要があります。
根本原因分析:自動化への過信と設計ミス
なぜ、これらの組織は失敗したのでしょうか? 技術的な設定ミスもさることながら、より深いレベルでの「設計思想」に問題がありました。
「署名=安全」という誤解
最大の根本原因は、署名を「安全性の証明書」だと勘違いしていた点です。署名は「同一性の証明」であって、「安全性の証明」ではありません。
署名が保証するのは、「署名された時点からファイルが変更されていないこと」だけです。「署名される前のファイルが安全であること」や「署名を行った人物(またはプロセス)が正当な権限を持っていたこと」までは保証しません。ケースAのように、悪意ある者が正規の鍵を使えば、悪意あるファイルに「正当な署名」が付いてしまいます。
モデルの来歴管理(Provenance)の欠如
失敗したパイプラインには、Provenance(来歴情報)の検証が欠けていました。
- どのソースコード(コミットハッシュ)から学習されたか?
- どのデータセットを使用したか?
- どのビルド環境(コンテナイメージ)で実行されたか?
これらの情報がモデルと紐付いておらず、かつ検証時にチェックされていませんでした。単に「鍵が合っているか」だけでなく、「信頼できるビルドプロセスを経て生成されたか」を確認する仕組みが必要だったのです。
検知アラートの形骸化と無視
運用負荷を減らすための自動化が、逆効果になることもあります。ケースBのように、検証エラーを「Warning」として処理し、パイプラインを止めない設定にすることは、開発スピードを優先する現場ではよくあることです。
しかし、セキュリティにおいて「Fail Open(失敗時は通す)」は致命的です。また、日常的に大量のWarningが出ている環境では、攻撃の兆候を示す重要なアラートもノイズに埋もれてしまいます。
見逃された警告サインと技術的兆候
攻撃が成功する前には、何らかの予兆があると考えられます。ここでは、システムログやメタデータに残されていたと考えられる「微細な異常」について解説します。これらを監視項目に加えることで、早期検知が可能になる可能性があります。
ハッシュ値の微細な不整合
攻撃者がモデルファイルを差し替えた場合、当然ハッシュ値は変わります。しかし、巧妙な攻撃では、モデルの重みパラメータの末尾数バイトだけを変更し、推論精度にほとんど影響を与えずにペイロードを埋め込むことがあります。
監視すべきは、「学習完了時のハッシュ値」と「アーティファクトリポジトリ(MLflowやS3)に保存されたハッシュ値」の一致です。ここが自動的に照合されていない場合、手動アップロードによる差し替えを見逃してしまう可能性があります。
署名タイムスタンプの異常
正規のCI/CDパイプラインであれば、モデルのビルド完了から署名までの時間は一定の範囲内に収まるはずです。もし、ビルド完了から数時間後や、深夜帯などの不自然な時間に署名が行われている場合、それは正規のパイプライン外で、盗まれた鍵を使って手動署名された可能性があります。
CI/CDログに残された痕跡
ケースAのような鍵の漏洩や不正使用の場合、CI/CD環境のアクセスログに痕跡が残ります。
- 通常とは異なるIPアドレスからのパイプライン実行トリガー
- 環境変数の読み取り(Export)操作のログ
- ビルドスクリプト(
pipeline.yamlなど)への一時的な変更と、直後のRevert(変更取り消し)
特に、「ビルド設定ファイルの変更」は要注意です。攻撃者は、署名プロセスを一時的に無効化したり、検証ロジックを書き換えるために設定ファイルをいじることがあります。
再発防止のための多層防御アーキテクチャ
失敗事例と原因を踏まえ、現代のMLOpsに求められる多層防御のアプローチを提案します。キーワードは「Keyless署名」と「SLSA」です。
Sigstore/Cosign等を活用した署名プロセスの強化
従来の「長い有効期限を持つ固定の秘密鍵」を管理するのはリスクが高すぎます。そこで推奨されるのが、SigstoreやCosignを用いたKeyless署名(キーレス署名)です。
これは、OIDC(OpenID Connect)を利用して、署名する瞬間にだけ有効な「短期的な証明書」を発行する仕組みです。Google CloudやAWS、GitHubのIDプロバイダと連携し、「この署名は、確かにGitHub Actionsの特定のワークフロー実行によって行われた」ということを証明できます。これにより、鍵管理の手間と漏洩リスクを減らすことが期待できます。
モデルハッシュと学習データの紐付け(Provenance)
SLSA(Supply-chain Levels for Software Artifacts)フレームワークの概念をMLOpsに適用しましょう。モデルファイルそのものへの署名に加え、「Provenance(来歴証明書)」を生成し、署名します。
具体的には、以下の情報を含むJSONファイルを作成し、モデルと一緒に署名・保存します。
{
"builder": {
"id": "https://github.com/my-org/my-repo/actions/runs/12345"
},
"recipe": {
"type": "https://cyclonedx.org/bom",
"definedInMaterial": 0,
"entryPoint": "train.py"
},
"materials": [
{
"uri": "git+https://github.com/my-org/my-repo@v1.0.0",
"digest": {
"sha1": "8d9c..."
}
},
{
"uri": "s3://my-data-bucket/training-set-v2.csv",
"digest": {
"sha256": "e3b0..."
}
}
]
}
推論環境では、モデルの署名だけでなく、このProvenanceを検証し、「許可されたリポジトリの、許可されたワークフローから生成されたモデルか」を確認します。
推論環境での実行時検証の自動化
デプロイ時のチェック(Admission Controller)だけでなく、実行時の監視も重要です。例えば、eBPFなどの技術を用いて、推論プロセスが予期せぬ外部通信(C2サーバーへの接続など)を行っていないか、許可されていないファイルシステムへのアクセスを行っていないかを監視します。
また、モデルロード時のデシリアライズ処理を安全に行うため、任意のコード実行リスクがあるpickle形式の使用は避けるべきです。代わりに、safetensorsやONNX(Open Neural Network Exchange)といった、よりセキュアなフォーマットへの移行を推奨します。
特にONNXについては、ONNX Runtimeの更新が継続的に行われており、最新版ではメモリ管理やデバイス情報の処理に関するAPIが拡張されるなど、安全性とパフォーマンスの両面で強化が進んでいます。Enterprise Postgresの最新版でもONNX形式のサポートが追加されるなどエコシステムも拡大しており、セキュアな推論基盤の標準的な選択肢として有効です。
あなたの組織のリスク診断チェックリスト
最後に、あなたの組織のMLOpsパイプラインがどの程度のリスクにさらされているか、簡易診断を行ってみましょう。以下の項目に「No」がある場合、そこが攻撃の突破口になる可能性があります。
鍵管理とアクセス制御の現状確認
- 署名鍵はHSM(ハードウェアセキュリティモジュール)やKMS(鍵管理サービス)で管理され、CI/CDツールから直接エクスポートできないようになっているか?
- 署名鍵へのアクセス権限は最小限(Principle of Least Privilege)に絞られ、定期的にローテーションされているか?
- パイプラインを実行するサービスアカウントの権限は、必要なリソース(特定のS3バケット等)のみに限定されているか?
パイプラインの検証ステップ網羅性
- 推論サーバーでのモデルロード前に、署名の検証を強制しているか?(検証失敗時にプロセスが停止するか?)
- 署名検証だけでなく、モデルの作成元(Provenance)や使用された学習データのハッシュ値まで検証しているか?
- 検証ロジック自体が改ざんされていないことを保証する仕組み(イミュータブルなインフラ、コード署名済みポリシー等)があるか?
インシデント対応フローの有無
- 署名検証エラーが発生した際、即座にセキュリティチームにアラートが飛ぶ仕組みになっているか?
- 万が一、汚染されたモデルがデプロイされた場合、直ちに以前の安全なバージョンにロールバックする手順が確立されているか?
まとめ:信頼をつなぐ鎖を強化する
AIモデルへの攻撃は、もはやSFの世界の話ではありません。コード署名は強力な武器ですが、それを扱うプロセスに穴があれば、容易に無力化されてしまいます。
重要なのは、点(ツール)ではなく線(プロセス)で守ることです。
- 鍵管理の脱却: Keyless署名やKMSを活用し、静的な鍵管理リスクを排除する。
- 来歴の保証: モデルだけでなく、その生成プロセス(Provenance)全体を検証対象とする。
- Fail Closed: 検証失敗時は確実に停止させ、例外を認めない。
これらを実践することで、MLOpsパイプラインは単なる「自動化ツール」から、ビジネスの信頼性を支える「堅牢な基盤」へと進化します。まずは現状のパイプラインを検証し、小さなプロトタイプからでも堅牢な仕組み作りを始めてみてください。安全なAI駆動開発が、皆さんのプロジェクトを成功に導くことを願っています。
コメント