🦙

MCP の認可 (2025-11-25) ~CIMD と EMA~

に公開

はじめに: 2025-11-25 版の MCP 仕様が公開

MCP の新しい仕様が公開されました。これまでは 2025-06-18 が最新でした。

この記事では、2025-11-25 の変更点について、認可におけるクライアント登録の部分にフォーカスをあてて解説します。

ベースは、MCP 公式の Authorization のページです。
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization

前提: MCP における認可の概要

前提となる考え方を簡単に紹介します。

リモート MCP サーバーでは認可の実装が推奨

MCP における認可機能の実装は OPTIONAL (任意) であり、必須ではありません。ただし、HTTP ベースのトランスポートを使用する場合、つまり、いわゆるリモート MCP サーバーの場合は SHOULD (推奨) のレベルで実装が求められます[1]

例えば以下のようなシーンでは認可が必須となるのではないかと思います。

  • 社内向けに、機密情報などを扱う MCP サーバーを内製して展開したい
  • MCP サーバーが提供するツールやデータへのアクセスを、ユーザー権限に応じて制限をかけたい

OAuth 2.1 が基盤

IETF で策定が進められている OAuth 2.1 を基盤としています。この文脈で MCP の登場人物にマッピングすると、以下のようになります。

  • リソースサーバー: MCP サーバー
  • クライアント: MCP クライアント (例: Claude Desktop、Cursor など)
  • 認可サーバー: 必要に応じて IdP (Okta、Entra ID など) が担う

Client ID Metadata Documents の導入と Dynamic Client Registration の格下げ

では本題に入っていきます。

OAuth 2.1 では一般的に、クライアントは事前に認可サーバーに登録されている必要があります。ただし MCP においては利便性のため、動的なクライアント情報の登録・提供を仕様として定めています。2025-11-25 の仕様では以下 3 つの方法が定められました。

  1. 事前登録
  2. Client ID Metadata Documents を使用する
  3. Dynamic Client Registration を使用する

※上記 3 つに加え、MCP クライアント側ではユーザーによる手動入力をサポートすることも推奨されています。

上記のうち 1 つ目の事前登録は、世界中の不特定多数の MCP クライアントから使用されることを想定した MCP サーバー (例えば Atlassian MCP や GitHub MCP など) では実質的に不可能です。そこで、このクライアントの登録を動的に行う仕組みとして 2025-06-18 から仕様化されていたものが Dynamic Client Registration (DCR) プロトコル (RFC7591[2]) でした。

DCR の課題

簡単に紹介すると、DCR は以下のような仕組みです。

  1. 初めて MCP サーバーに接続する際、クライアントは自身のメタデータを認可サーバーに送信
  2. 認可サーバーは動的にclient_idclient_secretを発行
  3. 発行された情報を用いて OAuth フローを開始

DCR は 2025-06-18 版の仕様では SHOULD として実装が推奨されていましたが、2025-11-25 版では MAY になり、後方互換性を意識した内容に変わりました。というのも、DCR には以下のような課題がありました。

  • 認可サーバーの DB が無制限に肥大化する
  • クライアントなりすましによるフィッシングや混乱した代理 (Confused Deputy) 問題など複数のセキュリティリスクへの対応が必要
  • DCR をサポートする認可サーバーが少ない

※3 つ目の認可サーバーの少なさについては、Okta や Google など公式認可サーバーの役割を拡張することで解決は可能です。その用途で使用できるライブラリが Cloudflare から提供されていたりします[3]

このような課題から、2025-11-25 で仕様化されたものが Client ID Metadata Documents です。

Client ID Metadata Documents (CIMD) の概要

2025-11-25 の仕様では Client ID Metadata Documents (CIMD, draft-ietf-oauth-client-id-metadata-document-00[4]) が SHOULD として推奨されるようになりました。

CIMD では、クライアントは認可サーバーから発行されるclient_idを持たず、その代わりにクライアント自身が保有する HTTPS URL (例:https://app.example.com/oauth/client-metadata.json)をclient_idとして使用します。その URL には以下のような JSON がセットされています。(これがメタデータドキュメントです)

{
  "client_id": "https://app.example.com/oauth/client-metadata.json",
  "client_name": "Example MCP Client",
  "client_uri": "https://app.example.com",
  "logo_uri": "https://app.example.com/logo.png",
  "redirect_uris": [
    "http://127.0.0.1:3000/callback",
    "http://localhost:3000/callback"
  ],
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

以下のような流れで認可を行います。(全体ではなく抜粋しています)

  1. MCP クライアントは、認可リクエストを送信する際にclient_idとして自身の URL (上記で例示した JSON = メタデータドキュメントが公開されている) を送信
  2. 認可サーバーは受け取った URL に対し、HTTP GET リクエストを送信
  3. 認可サーバーは取得した JSON を解析し、client_idが受け取った URL と一致するか検証
  4. 検証に成功した場合、メタデータを使用してユーザーへの同意画面を生成

以下は公式ドキュメントに載っているシーケンス図です。

CIMD が解決した DCR の課題

CIMD によって DCR のいくつかの課題が解決 (軽減) されました。認可サーバーはリクエストが来た際にクライアントのメタデータを外部から取得し、検証を経てそのセッション限りで (または一時的にキャッシュして) 情報を利用します。つまり永続化が不要であるため、認可サーバーの DB が無制限に肥大化する問題は解決しました。

また DCR では/registerエンドポイントを用いて自己申告の情報でクライアントを登録します。つまり、なりすましによるフィッシングのリスクがありました。CIMD ではclient_idにメタデータドキュメントの HTTPS URL(例: https://app.example.com/oauth/client-metadata.json)を渡し、認可サーバーはその URL から取得した JSON と URL の一致を TLS + DNS で検証することでクライアント登録を行うことなど (他にもclient_idの URL のホスト名表示などの対策が推奨されます[5]) により、そのリスクを軽減させています。

Stytch は Microsoft と協働して、認可サーバーとしていち早く CIMD に対応し[6]、MCP クライアントとしての VS Code と足並みを合わせました[7]

VS Code のメタデータはhttps://vscode.dev/oauth/client-metadata.jsonにあり、見てみると以下のようになっていました。

{
  "client_name": "Visual Studio Code",
  "grant_types": [
    "authorization_code",
    "refresh_token",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "application_type": "native",
  "client_id": "https://vscode.dev/oauth/client-metadata.json",
  "client_uri": "https://vscode.dev/product",
  "redirect_uris": ["https://vscode.dev/redirect", "http://127.0.0.1:33418/"]
}

CIMD に残る技術的な課題

DCR の課題の多くが解決されたとはいえ、CIMD には主に MCP クライアントに起因する以下のようなリスクがあります。

  • MCP クライアントが自ドメインで HTTPS のメタデータを公開する前提に立つため、信頼の起点がドメインに依存する。認可サーバーはドメインレピュテーションや初回警告など追加ポリシーを併用する必要がある。
  • MCP クライアントのメタデータ取得時、認可サーバーに対する SSRF/DoS を防ぐため、プライベートレンジ拒否・レスポンスサイズ/タイムアウト制限・短期キャッシュなどのポリシー実装の必要がある。

また、CIMD は主に事前登録なしで不特定多数のクライアントを受け入れるユースケースを想定のもと、設計されているのではないかと思います。社内向けに MCP サーバーを内製開発する場合を含め、エンタープライズ環境においては利用状況の可視化やスコープ制御などの観点から最適とは言えません。そこで出てくるのが Enterprise-Managed Authorization です。

ext-auth における Enterprise-Managed Authorization (EMA)

MCP には ext-auth という認可についての拡張仕様が定義されています[8]。どちらもドラフト段階ではありますが、OAuth Client Credentials と Enterprise-Managed Authorization (EMA) の 2 つが定義されています。今回は EMA について解説します。

中核となる概念は IETF で標準化が進められている「Identity Assertion Authorization Grant」(draft-ietf-oauth-identity-assertion-authz-grant-01[9]) で、一言で表現すると「既存の IdP を活用して MCP クライアントの認可を管理する仕組み」です。具体的には以下のような認可フローです。(OIDC 前提)

  1. ユーザーが MCP クライアントで MCP サーバーを有効化すると、自動的に IdP のログイン画面が表示される (ユーザーはそこでログイン)
  2. ログイン成功後、MCP クライアントは提供された認可コードを使って Identity Assertion の仕組みのための ID トークンを IdP から 取得 (この ID トークンは MCP クライアントに保存される)
  3. MCP クライアントは、Identity Assertion JWT Authorization Grant (ID-JAG) の仕組みを使って IdP から Assertion トークン (Identity Assertion JWT) を取得
  4. MCP クライアントは ID-JAG の仕組みを使って Assertion トークンを送信し、MCP サーバーの認可サーバーからアクセストークンを取得
  5. MCP クライアントはそのアクセストークンを使って MCP サーバーにアクセス

以下、公式ドキュメントのシーケンス図をそのまま掲載します。

EMA は OAuth クライアントの事前登録や認可範囲のコントロールが必要だったりと管理コストはかかりますが、以下のメリットがあります。

  • 組織内でどのような MCP サーバー (のツール) にどのような認可まで与えて良いのか IdP で制御できる。これにより利用状況を可視化できる
  • ユーザーに認可範囲の判断させずに済む (ユーザー目線: SSO で MCP サーバーが利用できる)

2025/11/26 現在、Okta が Cross-App Access として、 ID-JAG を利用した EMA の思想をほぼそのまま再現したサービスを IdP として発表しています。

https://www.okta.com/newsroom/press-releases/okta-introduces-cross-app-access-to-help-secure-ai-agents-in-the/

まとめ

CIMD と EMA について調査、解説してみました。どちらの仕組みも 特に MCP クライアントと認可サーバーでそれぞれ対応が必要だったり、EMA についてはドラフト段階だったりと、発展途上の領域です。引き続きウォッチしていきたいと思います。

気が向けば 2025-11-25 の仕様や CIMD に対応した MCP サーバーを構築してみようと思います。

記事の内容に不足や誤りがあればコメントでご指摘いただけますと幸いです。

脚注
  1. "Implementations using an HTTP-based transport SHOULD conform to this specification." ↩︎

  2. OAuth 2.0 Dynamic Client Registration Protocol ↩︎

  3. workers-oauth-provider / ほかに Python の FastMCP にも似たような機能を見つけました。 ↩︎

  4. draft-ietf-oauth-client-id-metadata-document-00 ↩︎

  5. OAuth Client ID Metadata Document - 6.4. OAuth Phishing Attacks ↩︎

  6. Stytch supports CIMD for OAuth ↩︎

  7. VS Code UPDATES: October 2025 (version 1.106) ↩︎

  8. MCP Authorization - 12.MCP Authorization Extensions ↩︎

  9. Identity Assertion Authorization Grant ↩︎

Discussion