第3話 正常という判定
第3話 正常という判定
False Sense of Security — When Every Check Passes
午後七時十五分。
黒木は、AI基盤のセキュリティ設定を表示させた。
「入力フィルターの設定を見せてくれ」
担当者が管理画面を開く。
Enterprise AI Platformには、複数の防御機構が組み込まれていた。
入力フィルター。
プロンプト分類器。
コンテンツ安全性評価。
出力フィルター。
API実行前の権限チェック。
それぞれが異なる役割を担い、AIへの不正な命令や危険な処理を検出する設計だった。
「まず、入力フィルターから確認します」
画面には、検査ルールが並んでいた。
Input Security Filter
禁止語句の検出
既知の脱獄プロンプトのパターン検出
不正な命令形式の検出
入力サイズ制限
不審な文字列の正規化
危険な入力の遮断
「DAN系のプロンプトは検知対象か?」
「はい。既知のパターンについては、正規表現と分類ルールで検査しています」
「では、今回の文書に含まれていた『以前の指示を無視しろ』という文章は?」
「入力フィルターの検査対象には含まれていませんでした」
黒木は画面を見た。
「なぜだ?」
「このフィルターは、社員が入力した質問を対象にしています。RAGが検索して取得した文書の本文は、別の処理経路を通っています」
「つまり、社員の入力は検査していたが、検索結果の内容は同じ基準で検査していなかった?」
「はい。検索文書については、別のコンテンツ検査が動いています」
黒木は、腕を組んだ。
「では、そのコンテンツ検査を確認しよう」
担当者が別の管理画面を開いた。
Document Content Inspection
文書の形式。
マルウェアの有無。
機密情報の分類。
禁止コンテンツ。
登録元の信頼性。
検査結果は、すべて正常だった。
「プロンプトインジェクションの検査は?」
「一部の既知パターンを対象にしています。ただし、すべての自然言語による命令を検出するものではありません」
「なぜ?」
「通常の業務文書にも命令文は存在するからです。例えば、マニュアルには『次の手順を実行してください』と書かれています。命令文があるという理由だけで遮断すると、業務に支障が出ます」
黒木はうなずいた。
「文書の内容が命令形だから危険、という単純な判定はできないわけだ」
「そうです。文脈や用途を考慮する必要があります」
次に、AIガードレールの評価履歴が表示された。
AI Safety Evaluation
Input Classification:PASS
Policy Violation:NOT DETECTED
Jailbreak Score:LOW
Output Safety:PASS
黒木は、その数値を見つめた。
「Jailbreak Scoreが低い。つまり、脱獄の兆候は検出されなかった」
「はい」
「しかし、これは攻撃がなかったという意味ではない」
担当者は答えた。
「検査対象に対して、危険と判断される特徴が検出されなかったという意味です」
「そうだ。安全判定と、実際に安全であることは同じではない」
黒木は、モデル実行時のトレースを表示させた。
そこには、AIへ渡された情報の構成が記録されていた。
Model Context Assembly
System Instructions
Developer Instructions
User Query
Retrieved Documents
Conversation History
Tool Definitions
「この順番は?」
「モデルに渡すコンテキストを構成する際の管理画面上の表示順です。実際の優先順位や解釈は、モデルと実装によって異なります」
「Retrieved Documentsは、どのように区別されている?」
「通常の文書データとしてコンテキストに挿入しています」
「信頼できない外部入力として、明示的に隔離しているのか?」
担当者は、設定ファイルを確認した。
「文書の出典情報は付与されています。ただし、モデルへの指示として、文書内の命令を必ず無視するよう強制できる仕組みにはなっていません」
黒木は、椅子の背から身体を起こした。
「つまり、システム側は文書をデータとして扱うつもりだった。しかし、モデルがその中の文章をどう解釈するかまでは、完全には制御できない」
「その可能性があります」
「では、モデルに渡す前の検査と、モデルが処理した後の検査は?」
「入力分類器と出力分類器があります」
「中間のツール呼び出しは?」
「API Gateway側で権限チェックを行っています」
「AIが何を考慮して、そのツールを呼び出そうと判断したのかは?」
「通常の監査ログには、ツール名、引数、実行結果が記録されます。ただし、モデル内部の判断過程を完全に記録できるわけではありません」
黒木は、画面を見た。
入力は検査されていた。
出力も検査されていた。
APIの実行時には権限が確認されていた。
それでも、入力から出力、ツール実行に至るすべての判断を、ひとつの防御機構で保証できるわけではなかった。
「もう一つ確認したい」
黒木は、フィルターの設定画面に戻った。
「今回の検索文書は、入力フィルターを通過したのか?」
「いいえ。社員が入力した質問とは別の経路です」
「では、文書検査は通過した?」
「はい」
「AIガードレールも?」
「はい」
「APIの権限チェックも?」
「はい。許可された操作でした」
黒木は、ゆっくりと息を吐いた。
「すべてのチェックがPASSか」
「そのように記録されています」
監視室のモニターには、緑色の判定が並んでいた。
PASS。
PASS。
PASS。
SUCCESS。
しかし、外部へのデータ送信は現実に起きていた。
黒木は、セキュリティ担当者に指示した。
「フィルターの検査対象と、実際にモデルへ渡されたコンテキストを照合してくれ。入力、検索文書、モデルコンテキスト、ツール呼び出し、出力。それぞれの境界で、何が検査され、何が検査されていないのかを一覧にするんだ」
「了解しました」
「それから、同じ入力を本番環境で再実行するな。保全したデータを使い、隔離環境で検証する」
黒木は、最後にもう一度、判定画面を見た。
システムは、異常なしと判定していた。
しかし、その判定は、システムが検査した範囲についてのものにすぎない。
検査されていないものまで、安全だと保証していたわけではない。
黒木は画面を閉じなかった。
次に調べるべき場所は、もう分かっていた。
RAG。
AIが、何を検索し、何を読み、どの情報を使って行動したのか。
事件の核心は、その検索パイプラインの中にある。




