「MCPの認証と認可(MCP Authorization)」を読む
#アプリケーションアーキテクチャ #アプリケーションアーキテクチャ #セキュリティ #設計原則 #ドメイン駆動設計(DDD)
#共有する
MCPの認証と認可 - MCP Meetup Tokyo 2025 - Speaker Deck
以下は「MCPの認証と認可(MCP Authorization)」のSpeaker Deck 発表内容(発表日:2025年9月5日)を、ソフトウェアエンジニア向けに要約・整理し、意訳も交えて分かりやすくまとめたものです。また、得られる教訓やインサイトについても最後に追記しています。
/icons/hr.icon
要点まとめ(箇条書き)
1. 話者紹介
発表者:赤松 弘樹(Akamatsu Hiroki)、メルカリAIセキュリティチーム所属。外部AIツールのセキュリティレビューや、社内のセキュリティ基盤整備などを担当。
2. MCPサーバーのセキュリティとベストプラクティス
リモートMCPサーバーの利用が推奨されており、既にAtlassian、Notion、Linearなどが公式に提供を開始。ローカル運用よりもセキュリティ的に好ましい。
3. リモートMCPサーバーを使うメリット
設定ファイルにアクセストークンを埋め込む必要がない
ユーザーごとの動作バージョンを統一できる
組織全体での利用状況が可視化しやすい→ セキュリティと管理性の向上につながる。
4. 内製MCPサーバー開発の機運と課題
複数サービスにまたがる処理をMCP化したい、あるいは公式にない機能や社内システムとの連携を実現したいとのニーズから、内製化の動きが出ている。
ただし、ローカルMCP(簡易運用)では以下の課題が発生:
設定ファイルにアクセストークンをハードコードしてしまう
ユーザーごとにバージョンが異なる混在状態
利用状況の可視化ができない
公式の認可仕様(URLのみで接続)を満たす環境構築が求められている。
5. 認可のプロセス(リモートMCPサーバー)
典型的な流れは以下の通り:
1. クライアントにMCPサーバーURLを追加・有効化
2. ブラウザでサービスにログイン
3. MCPクライアントがアクセス許可範囲を確認・承認させる
4. その後MCPサーバーが利用可能になる
→ このプロセス自体は標準的なOAuth風の流れと一致。
6. 認可仕様に潜む落とし穴
「URLだけ」で接続を可能にしようとすると、各サービスでのOAuthクライアントIDの事前登録/取得が必要になるという問題がある。
動的クライアント登録(Dynamic Client Registration, DCR)プロトコルを使えば自動化できるが、実際には普及しておらず広く使われていない。
7. Dynamic Client Registration(DCR)に関する現状
多くの認可サーバー(例:Okta、Google Cloud、GitHub、Atlassianなど)がDCRや認証なしDCRをサポートしていない。
DCRには以下のような課題も:
プロトコル未実装
管理者権限が必要
サービスごとの対応差異あり
→ URL接続を実現する自由度・自動化が困難。
8. 既存の対応手段と内製認可サーバーの負担
DCRに対応させるには、OAuthプロバイダーライブラリ(例:Cloudflare Workers用など)を使って独自認可サーバーを構築する必要がある。
内製には以下のような責任や知見が要求される:
OAuth仕様への正確な準拠
多数のアクセストークンやOAuthクライアントの安全かつ正確な管理
サービスごとの非対応状況への対応
DCRにおけるセキュリティ上の考慮(例えば RFC 7591の推奨事項)
9. 認可仕様の今後の展望
DCRを使わない新しい認可仕様の動きあり:
SEP-991:OAuth Client ID メタデータ文書を使ったURLベースのクライアント登録
SEP-1299(およびSEP-1415):クライアントセッショントレーシングによるサーバー側認可管理
また、IdP(例:Okta)を活用し、連携先各サービスごとにブラウザ操作する手間を省く「Enterprise-Managed Authorization Profile」構想(SEP-646)が進行中。ユーザー操作不要でトークン取得が可能になる試み。Oktaでは既にEA(Early Access)開始。
10. まとめと今後のアクション
現状、内製リモートMCPサーバーの提供には「認可仕様の壁」が存在する。DCRには使えるものの負担が大きく、本番運用には課題あり。
当面取れる対策(ToDo)としては:
アクセストークンの有効期限を短く設定
Keychainなど信頼できる安全な保管領域の活用
安全な使い方に関する周知(教育)強化
MCP仕様の変化や最新動向のキャッチアップ体制作り
/icons/hr.icon
ソフトウェアエンジニア向け 意訳ポイント
リモートMCPサーバー運用は、地味ですがセキュリティや運用効率に大きく貢献します。例えば、設定ファイルの漏洩リスクを回避し、全社的なバージョン統制が可能です。
OAuth周辺の自動化(DCRなど) は技術的に魅力的ですが、現状ではほとんどのプロバイダーが未対応。企業環境で「URLだけ」で接続したいと考える場合、多くのカスタム作業や運用コストが発生します。
標準化への期待:SEPシリーズ(SEP-991、SEP-646など)は、将来的には「IDプロバイダーにログインするだけで統合認可が完結する」世界を見据えた試み。エンジニアとして、仕様の進展や業界水準に注目しておく価値があります。
/icons/hr.icon
汲むべき教訓・インサイト
標準仕様と運用現実のギャップを正しく把握し、自社のセキュリティニーズおよび運用力と照らし合わせて判断することが重要。
内製化にはリスクと知識要求の両方がある。安易に「自前でつくればいい」という判断をせず、セキュリティ責任範囲や実装知識、運用体制を本当に担えるかを見極めよう。
外部サービスの進化に敏感であれ:Oktaなどが主導する次世代認可方式(SEP-646など)は、有効に使えば大きな効率化につながる可能性があるため、情報収集や早期検証を積極的に。場合によっては社内PoCの対象にしても良いでしょう。
今できるセキュリティ対策を着実に実施:たとえばトークンの短期化や安全な保管、組織への啓蒙といった積み重ねが将来的な仕様変更への備えになります。
/icons/hr.icon
1. MCPサーバーが提供する機能
MCP サーバーは「AIエージェントにとっての API アダプター」のような役割を果たします。
具体的には:
ツール呼び出し(Tools)
例:検索、チケット作成、タスク登録、翻訳など
サーバー側で API を叩き、その結果を MCP クライアント(Claude や IDE拡張など)に返す。
リソースアクセス(Resources)
文書やデータを「参照」できる。
例:カレンダー予定一覧、Notionのドキュメント、GitHubリポジトリ情報など。
Prompts / Templates
共通のプロンプトやテンプレートをサーバー側で管理し、クライアントから呼び出して利用可能にする。
組織内のシステムとの統合
公式MCPが提供されていない SaaS や 社内の独自システムを「MCP化」して、AIクライアントから利用可能にする。
/icons/hr.icon
2. 社外 MCPサーバーの扱い
はい、ご指摘のとおり 社外の MCP サーバーを複数まとめて利用する ことができます。
記事でも紹介されているように、例えば:
Atlassian MCP → Jira や Confluence を操作
Notion MCP → ノートやデータベースにアクセス
Linear MCP → タスク管理連携
これらを「クライアント(例:Claude Desktop、VSCode拡張)」から一括で接続でき、ユーザーは統一された UX で操作できます。
つまり:
エンドユーザー(エンジニアや社員)は MCP クライアントを通して一元的に利用
裏側では MCP サーバーが API 呼び出しや認可処理を吸収・代理
という構造です。
/icons/hr.icon
3. 内製 MCPサーバーの文脈
記事が強調しているのは、社内でも 複数サービスをまたいでまとめたい場合や公式 MCP が存在しない場合、自社で MCP サーバーを立てるニーズ が出てきている、という点です。
ただし認可やトークン管理のハードルが高く、DCR(動的クライアント登録)や今後の標準仕様(SEPシリーズ)が重要になる、というのが発表の論点でした。
/icons/hr.icon
🔑 まとめると:
MCPサーバーは「AIエージェントに安全かつ統一的に外部サービスを使わせるためのゲートウェイ」
社外サーバー(Atlassian, Notion, Linear など)をまとめて接続して使える
社内でも「社外API + 社内システム」を統合する MCP サーバーを立てる動きが出てきている
/icons/hr.icon
社内の閉域網APIを MCP 経由で LLM(エージェント)に使わせる ときの認証認可まわりを、実務でそのまま設計に落とせる形でまとめます。
基本方針(まず結論)
LLM ⇄ API を直接つながない。
つなぐのは「LLM ⇄ MCPサーバ ⇄(認可ゲート)⇄ 社内API」。MCPサーバが“唯一の境界(policy enforcement point)”。
ユーザー委譲と機械間を分ける。
人の操作を代理するときは OIDC/OAuth2(Auth Code + PKCE)、自動バッチやエージェント専用は Client Credentials で。
短命&束縛されたトークン。
短い有効期限+PoP(DPoP か mTLS)でトークン盗難耐性 を上げる。長期のリフレッシュは MCP サーバ内でのみ保持。
最小権限+多層。
スコープ/ロールを極小に、OPA/Rego などのポリシーで二段階フィルタ(MCPで“何ができるか”と、API側で“誰に対して何を返すか”)。
/icons/hr.icon
推奨アーキテクチャ
1) トラスト境界
MCPサーバは社内側(閉域)に配置し、外部LLMクライアントからは リバースプロキシ/ゲートウェイ 経由の到達のみ許可。
LLMクライアント(例:Claude/IDE拡張)は リモートMCP へ接続。LLMから社内APIへは直接到達不可(FW/Egressで遮断)。
2) アイデンティティ & トークン
企業IdP(Azure AD/Entra、Okta、Auth0、Keycloak など)を 唯一のIdP に。
ユーザー委譲フロー:Authorization Code + PKCE(ブラウザでログイン/同意)→ MCPが (短命)アクセストークン を取得。
機械間フロー:Client Credentials(“MCPサーバ用の” クライアントID)→ audience を 社内APIのみに限定。
トークン交換(RFC 8693):MCPが受けたユーザートークンを audience絞りの“下流API用トークン”に交換。上流トークンは保護して露出しない。
3) トークン保護(必須)
**短命(5〜15分)**のアクセストークン+**リフレッシュトークンはMCPサーバ内の安全領域(HSM/KMS/OSキーチェーン/Secretsマネージャ)**でのみ保持。
DPoP もしくは mTLS(SPIFFE/SPIRE 推奨) で Proof-of-Possession を付与(cnf/x5t#S256/jkt などのバインド)。
JWTは aud/iss/exp/nbf を厳格検証。azp/act(委譲元)や cnf を活用。
4) 認可(きめ細かく)
RBAC + ABAC:ロール(例:issue:read)× 属性(プロジェクト、部門、データ分類)。
OPA/Rego を MCPサーバ or API Gateway に組み込み、「誰が・どのリソースに・どの操作」 を一元判定。
データ最小化:MCPツールは 既定で読み取り専用。書き込みは 明示の同意(step-up) を要求。
高リスク操作はステップアップ認証(WebAuthn/OTP)+ 人の承認(human-in-the-loop) オプション。
5) API ゲートウェイでの追加防御
mTLS終端、JWT検証、レート制限、IP/ネットワーク制限(閉域)。
スコープ→パス/メソッドのマッピング(例:tickets:write なら POST /tickets のみ)。
監査ログ:who/what/when/why/context(呼び出し元セッション/プロンプト要約/ツール名)を改ざん耐性ストアへ。
6) MCP(ツール)設計のポイント
明示的パラメータのみをAPIへ渡す(LLMの自由記述をそのまま送らない)。サーバ側でスキーマ検証。
プリセット/テンプレは MCP サーバに置き、危険語・機密カテゴリのDLPフィルタで出入りのテキストをサニタイズ。
リソース単位の権限制御(例:プロジェクトAのIssueだけ見えるツールと、Bは別ツール)。
結果のマスキング(例:個人情報や秘匿IDはトークン化して返す)。
/icons/hr.icon
運用ベストプラクティス(チェックリスト)
認証
IdPを一本化(OIDC/OAuth2)。
Auth Code + PKCE(人間)/ Client Credentials(機械)を用途で分離。
SPoC: MCPサーバ以外はトークンを保持しない。
トークン
有効期限 5–15分、リフレッシュはMCPのみ保持。
DPoP or mTLS でトークン束縛。
RFC 8693 Token Exchange で audience を最小化。
スコープは CRUD×リソース粒度で細分化。
ネットワーク
LLMクライアント→MCP のみ到達可。MCP→API は閉域内。
egress/egress-proxy 制御、DNS制限、FWの最小許可。
API Gateway でJWT検証+レート制限+WAF。
ポリシー/監査
OPA/Rego等でポリシーをコード化&レビュー/テスト。
高リスク操作は step-up + 人承認。
監査ログ(誰が何を要求→最終的に何を呼んだか)を一元収集&アラート。
秘密管理
KMS/HSM/Secrets Manager。
キーローテーション自動化。
キャッシュはプロセスメモリ限定、永続化禁止。
安全なUX
ツールごとに「できること」を明示表示。
書き込み時は毎回ユーザー確認 or ポリシーでホワイトリスト化。
出力にデータ分類ラベル(Internal / Confidential など)。
/icons/hr.icon
代表的な構成パターン
Good(最小構成)
IdP + API Gateway + MCPサーバ(閉域)
Auth Code/Client Credentials、短命JWT、最小スコープ、監査ログ
Better
上に加えて DPoP/mTLS束縛、Token Exchange による audience 絞り、OPA/Rego
Best
SPIFFE/SPIREでmTLSワークロードID、機密DLP/PIIマスキング、高リスク操作に人承認、
リソースレベルABAC、改ざん耐性の監査ログ保管(WORM/SIEM)
/icons/hr.icon
よくある落とし穴
クライアント側設定ファイルに 長期トークンを埋め込む(厳禁。必ずリモートMCP+短命トークン)。
aud が広いトークンの再利用(横展開リスク)。
LLMの自由記述をそのままAPIに渡し 意図せぬ“広域検索/大量更新” を引き起こす。
監査不足(プロンプト・ツール・下流APIの紐付けが追えない)。
/icons/hr.icon
参考の擬似設定イメージ(観点だけ)
code: (yaml)
mcp:
tools:
- name: jira.read
flow: auth_code_pkce
scopes: "issue:read"
token_binding: dpop
audience: ["https://api.corp.local/jira"]
policy: opa://policies/jira_read.rego
- name: cmdb.sync
flow: client_credentials
scopes: "cmdb:write"
mTLS: spiffe://ns/ai/workload/mcp
audience: ["https://api.corp.local/cmdb"]
gateway:
jwt:
require: ["iss == https://idp.corp", "aud == service", "exp<15m"]
ratelimit: "user:60rpm, service:200rpm"
waf: enabled
audit:
fields: user, tool, scope, resource, prompt_hash, decision, ts
sink: "siem+worm"