MCPサーバーの認可——つなぐ前に切る権限

Alex Ishiguro • • • 読了目安:6分
MCPサーバーの認可——つなぐ前に切る権限
目次▼
  1. 1結論を先に
  2. 2まず用語の地図
  3. 3具体例
  4. 4監査ログの粒度をどこまで取るか
  5. 5壊れたときの見え方を設計する
  6. 6よくある偏り
  7. 7いまの一手

MCPサーバーを「とりあえず動いた」で本番に出すかどうかは、スコープ・監査ログ・障害時の視認性の三点で判断する。


この記事の使い方

項目内容
決めることMCPサーバーに与えるスコープの粒度、監査ログの保存先と保存期間、障害時に何が見えるかの確認方法
決めないことどのMCPサーバー実装を選ぶか、LLMのモデル選定
前提MCP(Model Context Protocol)の基本的な接続手順は把握済み。OAuth 2.0の用語が出てくるが、詳細な実装経験は不要

結論を先に

判断軸最低ライン本番基準
スコープツール単位で読み取り/書き込みを分離リソース種別×操作種別のマトリクスで付与
監査ログツール呼び出しのin/outを記録タイムスタンプ・呼び出し元セッションID・結果コードを含む構造化ログ
壊れたときの見え方エラーがLLMに素通りせず呼び出し元に返る権限エラーと接続エラーを区別してアラートを分岐できる
トークン有効期限設定されている短命トークン(1時間以内)+リフレッシュフロー
取り消し経路手動で無効化できる管理画面またはAPIで即時失効できる

まず用語の地図

用語かみ砕いた意味
MCP(Model Context Protocol)LLMがツールや外部データソースを呼び出すときの共通の「話し方の規約」。Anthropicが策定し、各社が実装している
スコープ(scope)トークンに紐づいた「何をしていいか」のリスト。read:files と write:files は別スコープとして分けるのが基本
OAuth 2.0「誰が・何の権限で・どのリソースに触れるか」を第三者に委任する認可の枠組み。MCPサーバーはこの上に乗ることが多い
ツール呼び出し(tool call)LLMがMCPサーバーに「この関数を実行してくれ」と依頼する一連のやり取り。引数と戻り値がある
監査ログ(audit log)誰が・いつ・何を呼んで・どうなったかの記録。障害調査とコンプライアンス対応の両方に使う
最小権限原則(least privilege)動作に必要な最低限の権限だけを与え、余分なスコープは持たせないという設計思想
トークン失効(revocation)発行済みのアクセストークンを無効にする操作。漏洩時や退職者対応で即時実行できるかが問われる

具体例

場面:社内ドキュメント検索ツールをMCP経由でLLMに接続する

社内のConfluenceライクなドキュメント管理システムをMCPサーバー経由でLLMに接続するケースを縦に切る。

構成の概略

LLM(Claude / GPT-4o など)
  └─ MCPクライアント
       └─ MCPサーバー(社内ドキュメント検索)
            └─ ドキュメントAPI(読み取り専用エンドポイント)

スコープ設計の実例

操作付与するスコープ付与しないスコープ
全文検索docs:searchdocs:write, docs:delete
ページ本文の取得docs:readdocs:read:confidential(機密ラベル付きページ)
添付ファイルのダウンロードdocs:attachments:readdocs:attachments:write

ポイントは「検索できる=全部読める」にしないこと。機密ラベルを別スコープに分離しておくと、LLMに渡すトークンから機密ページへのアクセスを物理的に切れる。


受け入れ条件とチェックリスト

本番投入前に以下を確認する。

  • MCPサーバーが受け取るトークンのスコープ一覧を列挙し、不要なものを削除した
  • ツール呼び出しのリクエスト(引数)とレスポンス(結果)が両方ログに残る
  • ログにセッションIDが含まれ、どのLLMセッションからの呼び出しか追跡できる
  • 権限エラー(403)と接続エラー(5xx)が区別されてアラートに出る
  • トークンの有効期限が設定されており、期限切れ時の挙動をテスト済み
  • トークンを即時失効させる手順が文書化されており、担当者が実行できる
  • 機密ラベル付きページへのアクセスを試みたとき、MCPサーバーが403を返すことを確認した

失敗モード一覧

失敗パターン症状根本原因対処
スコープ過剰付与LLMが意図しないページを取得・要約するdocs:read に機密ページが含まれていた機密ラベルを別スコープに分離
ログ欠損障害後に何が呼ばれたか追えないツール呼び出しのレスポンスをログしていなかったin/out 両方を構造化ログに書く
エラー素通りLLMが権限エラーを「データなし」と解釈して誤回答MCPサーバーが403をLLMにそのまま渡していたエラーコードを呼び出し元に返す処理を追加
トークン無期限退職者のセッションが残り続ける有効期限を設定していなかった短命トークン+リフレッシュフローに切り替え
失効手順不在漏洩時に即時対応できない管理手順が文書化されていなかった失効APIのRunbookを用意する

監査ログの粒度をどこまで取るか

ログを「取る」と決めたあと、粒度の設計で迷うことが多い。だいたい3層に分けて考えると整理しやすい。

層記録する内容用途
呼び出し層ツール名・引数・タイムスタンプ・セッションID障害調査・不正利用の検出
認可層スコープ検証の結果・付与されたスコープ一覧コンプライアンス監査
結果層レスポンスのステータスコード・データ件数(本文は原則マスク)パフォーマンス監視・エラー分類

レスポンスの本文をそのままログに書くと、個人情報や機密情報がログストレージに流れ込む。件数やステータスコードに留め、必要なときだけ再取得できる設計にする。

保存期間は組織のポリシーに従うが、最低でも「LLMのセッション単位で遡れる期間」は確保する。セッションが90日保持されるなら、ログも90日以上残す。


壊れたときの見え方を設計する

認可エラーは「静かに失敗する」ことが多い。LLMがエラーレスポンスを受け取っても、プロンプトの文脈で「情報がなかった」と解釈して先に進んでしまう。これが最も見落とされやすい障害モードだ。

エラー分類とアラート分岐の例

エラー種別HTTPステータス意味アラートの向き先
認可エラー403スコープ不足またはトークン失効セキュリティ担当・即時通知
認証エラー401トークン期限切れ・不正セキュリティ担当・即時通知
サーバーエラー500/503MCPサーバー側の障害インフラ担当・通常アラート
タイムアウト408/504ネットワーク・負荷インフラ担当・通常アラート

403と401を「接続できなかった」と一括りにしてインフラアラートに流すと、権限設定のミスや漏洩を見逃す。認可系エラーは別チャンネルに出す。


よくある偏り

「動いた=安全」という確認の省略

MCPサーバーが正常に応答を返すと、スコープの検証を後回しにしがちだ。動作確認と権限確認は別のテストケースとして分けて実施する。

ログを「取る」だけで「読む」設計がない

ログを書き出しても、誰がいつ何をトリガーに読むかが決まっていないと、障害後に「ログはあるが追えない」状態になる。ログの読み手と読むタイミングをRunbookに書いておく。

スコープを広げる方向にしか変更しない

開発中に「動かないから権限を足す」を繰り返すと、本番時点でスコープが膨らんでいる。変更のたびに「この権限は本当に必要か」を確認するレビューステップを挟む。

失効手順を「あとで作る」にする

トークン失効の手順は、漏洩が起きてから作るのでは遅い。接続を本番に出す前に、失効→確認→再発行の一連の手順を一度実際に通しておく。


いまの一手

本気の人

  1. 接続するツールごとに「読み取り」「書き込み」「削除」を別スコープに分離し、LLMに渡すトークンに含めるスコープを書き出す
  2. ツール呼び出しのin/outを構造化ログ(JSON)で書き出す実装を先に作り、機能実装より前に動作確認する
  3. 403と401のエラーを意図的に発生させ、アラートが正しいチャンネルに飛ぶことを確認する
  4. トークン失効のRunbookを1ページで書き、担当者が一人でも実行できる状態にする

まだ様子見の人

  • まず「このMCPサーバーが書き込み権限を持つ必要があるか」を問い直す。読み取り専用で済むなら、書き込みスコープは最初から渡さない
  • 監査ログの保存先(どのサービスに書くか)だけ先に決めておく。実装は後でも、保存先が決まっていれば設計がぶれない

connectors シリーズの他の記事はこちら → https://www.kakogenzai.com/ai/connectors/

A

Alex Ishiguro

編集長

MakuakeやCAMPFIREで話題になった商品の「その後」を追うメディアを運営。約束されたものが実際に届いたのか、消えてしまったのかを記録する。

この記事に追加情報や訂正がある場合は、お問い合わせよりご連絡ください。