8月5日、devops.comにてShadi Elyafiが「From API Integration to Agent Governance: What Backend Teams Need to Know About MCP」と題した記事を公開した。LLMエージェントへのバックエンド公開において、従来のAPIアクセス制御では防ぎきれないリスクが存在する——この問題意識を出発点に、MCP(Model Context Protocol)のガバナンス設計をスキーマ・パーミッション・ログ・テストの4軸で実践的に解説している。
MCP(Model Context Protocol)は、LLMがバックエンドのツールやデータソースを呼び出すための標準プロトコルだ。APIをMCPツールとしてラップすることで、ユーザーは固定UIを操作する代わりに自然言語でデータを取得できるようになる。ただし、操作を選択するのはアプリケーションコードではなくモデルになる——これが従来のAPI統合との本質的な違いであり、ガバナンス設計が必要になる理由だ。
Elyafiが所属するFullinfoでは、100万件以上の企業プロファイルをAWS AppSync上のGraphQLバックエンドで提供している。MCP導入により、「従業員数50〜200人のドイツのSaaS企業を探して」という自然言語クエリで構造化データが返せるようになった。ラッパー自体はTypeScriptとGoで比較的簡単に書けたが、モデルの権限範囲をどう定義するかに最も時間がかかったという。
なぜ既存のAPIアクセス制御だけでは足りないか
MCPを介すと、ツール名・説明文・スキーマの変更だけでモデルが呼び出す操作が変わる。汎用的なGraphQLツール(run_graphqlのような)はクエリ構築をモデルに委ねることになり、意図しない操作が実行されるリスクがある。また、プロンプトログだけではどのツールが選択されたか、どのリソースにアクセスされたかが追跡できないケースもある。
公式のMCPセキュリティガイドラインはいくつかの攻撃ベクタをカバーしている。たとえばconfused deputy攻撃(信頼されたエージェントが権限外の操作を実行させられる問題。詳細はOWASP解説も参照)、SSRF(サーバーサイドリクエストフォージェリ。エージェント経由でバックエンドから内部ネットワークへ不正リクエストが送出される脆弱性)、トークンパススルー、セッションハイジャックなどだ。ただし、これらのガイドラインが対処するのはプロトコルレベルのリスクであり、自分のツール定義が生むリスクは別途管理が必要になる。
実装の核心:4つのガバナンス設計
1. パーミッションレベルでツールを分離する
Fullinfoでの実装では、ツール登録の前に操作をパーミッションレベルで分類した。
| 種別 | 例 | 条件 |
|---|---|---|
| 読み取り | search_companies |
ユーザーが既に同データへのアクセス権を持つ場合は有効化可 |
| 書き込み | create_collection |
承認フローとフィーチャーフラグが整うまで無効 |
| 破壊的操作 | delete_collection |
ロールバック手順が確立するまでMCPから除外 |
読み取りツールでも、ユーザースコープの認可・結果件数の上限・スキーマテスト・監査ログはすべて必要だ。
2. スキーマでポリシーを強制する
これが記事の中で最も実装に直結するポイントだ。run_graphqlやquery_databaseのような汎用ツールは実装コストが低いが、クエリ構築を確率的なシステム(モデル)に渡すことになる。専用ツールはコードが増えるが、制約がバックエンドに到達する前に可視化・強制できる。
Fullinfoのsearch_companiesツールでは以下の制約をスキーマで定義している:
- クエリ長を200文字以内に制限
- 国コードはISO-2形式のみ許可
- 従業員数範囲はサポートする値のみ
- デフォルト件数10件、ハードリミット50件
.strict()で未知フィールドを無視せずリジェクト
さらにツールのdescriptionフィールドにも同じ制約を自然言語で記述する。「Read-only company search. Returns at most 50 summaries. Cannot create, update, export, or delete data」のように書くことで、モデルがツールを選択する際の根拠が明確になる。ツール名と説明に書いた制限は、バックエンドの認可ロジックと必ず一致させること。
3. ツール呼び出しをバックエンド操作として記録する
プロンプトだけをログに残しても、モデルが誤ったツールを選んだのか、バックエンドが想定外のデータを返したのかが判断できない。各呼び出しには以下を記録する:
ユーザー・テナント・ツール名・スキーマバージョン・サニタイズ済みパラメータ・バックエンド操作・認可結果・レイテンシ・最終ステータス。ブロックされたmutationはセキュリティイベントとして記録する。
4. チャットクライアントの外でテストする
チャット画面はUX確認には使えるが、モデルの挙動が実行ごとに変わるため、バックエンド保証のテストハーネスとしては不十分だ。MCP Inspectorを使えば会話モデルを経由せずにツールを直接呼び出せる。
Fullinfoの実装でこの分離が実際に問題を発見した。あるmutationがモックのユニットテストをパスしていたが、本番相当のバックエンドに対してはAppSyncリゾルバがnullポインタエラーを返した。このツールは統合パスが検証されるまでMCP登録から除外された。ユニットテストはラッパーの動作を証明するが、実際のバックエンドが操作を受け付けるかは証明しない。
まとめ:MCPレイヤーはアクセス制御設計の一部
記事の結論は明快だ。モデルがバックエンド操作を選択できるようになった時点で、MCPレイヤーはアクセス制御設計の構成要素になる。本番デプロイは、ユーザーの既存アクセス権と一致した型付き・読み取り専用ツールから始め、実際の統合パスのテストと承認プロセスが整ってから書き込みアクセスを追加する。破壊的操作は、ロールバックとインシデント対応手順が確立するまで公開しない——という段階的アプローチが推奨されている。
※編集部の考察:日本のバックエンドエンジニアにとって特に注目すべきは「ツール定義がそのままセキュリティポリシーになる」という発想の転換だ。RESTやGraphQL時代には、スキーマ設計とアクセス制御は別レイヤーで議論されることが多かった。MCPではその境界が曖昧になり、descriptionフィールドの記述ひとつがモデルの行動制約を左右する。設計段階からセキュリティチームを巻き込む必要性が、これまで以上に高まっている。
詳細はFrom API Integration to Agent Governance: What Backend Teams Need to Know About MCPを参照していただきたい。