LLMゲートウェイを導入しても、APIキーと利用料金をまとめただけでは、AIエージェントの事故は止められません。モデルへの入力、MCPツールの呼び出し、実システム上の操作を、それぞれ別の境界で制御する必要があります。
この記事では、企業内でLLMやAIコーディングエージェントを利用するときの統制を、次の3層に分けて整理します。
- Content Gateway:モデルに何を送受信できるか
- MCP Gateway:どのツールを、どの引数で呼べるか
- Runtime Authorization:その利用者が、その操作を実行してよいか
製品選定より前にこの境界を決めておくと、PoCから本番へ移るときの手戻りを減らせます。
1台のゲートウェイにすべてを期待すると境界が曖昧になる
一般的なLLMゲートウェイは、認証、モデルルーティング、レート制限、コスト集計、監査ログを中央化します。これは重要ですが、AIエージェントが外部ツールを使う環境では、次の操作がゲートウェイの外で起こることがあります。
- MCPサーバーから業務DBを検索する
- GitHubのIssueやリポジトリを更新する
- メールやチャットへ外部送信する
- 端末上でシェルコマンドを実行する
入力プロンプトが安全でも、ツールの権限が広ければ事故は起きます。逆に、不審な命令を完全に検知できなくても、書き込みや外部送信の権限がなければ被害を抑えられます。
そこで、検査対象と拒否責任を3層に分けます。
Content Gatewayは「何をモデルへ渡したか」を管理する
Content Gatewayの責任は、モデル呼び出しの入口と出口です。最低限、次の情報を同じtrace_idに結び付けます。
| 対象 | 記録・制御する項目 |
|---|---|
| 利用者 |
user_id、team_id、project_code
|
| モデル | 許可モデル、リージョン、フォールバック先 |
| 入力 | データ分類、秘密情報、個人情報、添付元 |
| 出力 | URL、コード、秘密情報、有害コンテンツ判定 |
| 利用量 | トークン数、予算、RPM/TPM |
プロンプト全文を常時保存すると、監査基盤自体に機密情報が集まります。通常ログはメタデータと判定結果を中心にし、本文が必要なデバッグは、対象者、期間、自動削除時刻を限定した例外運用に分けた方が安全です。
ポリシーの適用点は、入力と出力を分離します。
policy_hooks:
llm_input:
- classify_data
- detect_secrets
- enforce_model_allowlist
- enforce_budget
llm_output:
- detect_sensitive_output
- inspect_external_urls
- record_policy_result
このYAMLは製品固有の設定ではなく、責任分界を表す概念例です。
MCP Gatewayはツール名だけでなく引数まで見る
MCPサーバーを許可しただけでは、ツールの安全性は決まりません。同じGit操作でも、読み取りと削除では影響が違います。登録単位を「MCPサーバー」だけで終わらせず、ツールと操作の粒度まで下げます。
| 管理項目 | 例 |
|---|---|
| 所有者 | 開発基盤チーム |
| 接続先 | GitHub Enterprise |
| ツール |
read_issue、create_pr、delete_branch
|
| データ分類 | 社内限定、顧客機密あり |
| 副作用 | read / write / export / delete |
| 承認 | writeは自動、deleteは人間承認 |
| 変更管理 | Tool schemaの差分レビューと署名 |
ツールの説明文や引数スキーマも攻撃面です。ソースコードに変更がなくても、説明文が書き換わればエージェントの判断は変わります。そのため、Tool schemaを構成管理し、変更差分を監査対象に含めます。
mcp_tools:
- server: github-enterprise
tool: read_issue
effect: read
approval: automatic
- server: github-enterprise
tool: create_pr
effect: write
approval: policy
- server: github-enterprise
tool: delete_branch
effect: delete
approval: human
Runtime Authorizationは「誰が何に作用できるか」を最後に判定する
Content GatewayとMCP Gatewayを通過しても、操作対象ごとの認可が残ります。Runtime Authorizationでは、利用者、エージェント、操作、対象リソース、承認状態を組み合わせて判定します。
allow = (
user.role == "developer"
and agent.id in approved_agents
and action == "create_pull_request"
and resource.repository in user.assigned_repositories
and request.risk_score < 70
)
高リスク操作は、検知器の判定だけで自動許可しません。削除、外部送信、本番変更、権限付与、金銭に関わる操作には、人間による承認を残します。
IdP上の所属だけでは判定が粗すぎます。「開発部だから全リポジトリに書き込める」という許可を避け、プロジェクト、環境、操作種別、対象リソースまで絞ります。
間接プロンプトインジェクションはツール応答後にも検査する
利用者の入力だけを検査しても、Webページ、メール、RAG文書、MCPツールの戻り値に埋め込まれた命令は残ります。この経路を扱うには、少なくとも4つのフックが必要です。
| フック | タイミング | 主な検査対象 |
|---|---|---|
llm_input |
モデル呼び出し前 | 利用者入力、添付 |
llm_output |
モデル応答後 | URL、コード、秘密情報 |
mcp_pre_tool |
ツール実行前 | ツール名、引数、権限 |
mcp_post_tool |
ツール応答後 | Web、メール、DB、RAG由来の内容 |
mcp_post_toolで不審な内容を検知した場合は、単に文章へ警告を付けるだけでなく、その後のwrite、export、deleteを人間承認へ引き上げます。検知結果を認可判断へ戻す設計です。
監査ログは5種類の出来事を1本につなぐ
事故調査で必要なのは、チャット履歴だけではありません。次の出来事を同じtrace_idで追えるようにします。
- 誰が、どのエージェントを起動したか
- どのモデルへ、どのデータ分類の入力を送ったか
- どのMCPツールが選ばれたか
- 認可エンジンが何を根拠に許可・拒否したか
- 外部システムで何が実行されたか
ログに秘密情報そのものを残す必要はありません。key_idはキー本体ではなくハッシュ化識別子を記録し、プロンプト本文は原則として保存しない設計にします。
Phase 1では境界と証跡を先に固定する
最初から高度な検知器をそろえる必要はありません。Phase 1では、後から変更しにくい境界とログを優先します。
- 仮想キーまたは短命トークンで利用者とプロジェクトを識別する
- 許可モデルと月次予算を限定する
- MCPサーバーとツールの登録台帳を作る
-
trace_idをLLM、MCP、認可、業務ログへ伝搬する - write、export、deleteを人間承認へ送る
- キー失効とインシデント初動を手順化する
DLPやインジェクション検知の精度は、運用データを見ながら改善できます。一方、識別子や監査ログの設計がばらばらだと、後から相関できません。
本番前チェックリスト
- 開発者端末にプロバイダーの共通APIキーを配っていない
- 利用者、チーム、プロジェクトをログで識別できる
- 未許可モデルと予算超過を拒否できる
- MCPサーバー、ツール、所有者、データ分類の台帳がある
- read / write / export / deleteを区別している
- 高リスク操作に人間承認がある
- ツール応答をモデルへ戻す前に検査できる
-
LLM、MCP、認可、業務操作を同じ
trace_idで追える - キーや認証情報を即時失効できる
- ログ基盤が停止した場合のfail-open / fail-closedを合意している
まとめ
LLMゲートウェイは、モデルAPIを1本化するだけの仕組みではありません。企業でAIエージェントを動かすなら、入力と出力を扱うContent Gateway、ツールを扱うMCP Gateway、実際の権限を判定するRuntime Authorizationに責任を分ける必要があります。
最初に固定すべきなのは、高度な検知モデルより、利用者とプロジェクトの識別、ツール台帳、操作別の認可、共通trace_idです。この4点がそろえば、PoCで得た知見を本番統制へつなげやすくなります。
同じ観点で自社の不足を確認できる診断票を準備中です。