Skip to content

Evolving OAuth Client Registration in the Model Context Protocol

以下の翻訳です。
https://blog.modelcontextprotocol.io/posts/client_registration/

The Model Context Protocol (MCP) は、認可フレームワークの基盤として OAuth 2.1 を採用しました。MCP が特に強く依存している認可フローの重要要素が client registration です。

これは、クライアントとサーバーが事前に関係を持っているとは限らない世界では特に重要です。どの MCP client がどの MCP server に接続するのかを常に把握できるとは想定できません。この設計は、解決すべき 2 つの課題を浮き彫りにします。

  • Dynamic Client Registration(DCR)を通じた client ID 管理における運用上の問題
  • クライアントのなりすまし(impersonation)の防止

OAuth と、MCP における client registration の現状にすでに詳しい場合は、「MCP における client registration の 2 つの異なる課題」へ進んでください。

Background on OAuth

OAuth 2.1 を実装する保護された MCP server は、ユーザーがクライアントに対して自分自身(そのサーバー)へのアクセスを許可できるようにしつつ、フィッシングなどによってユーザーを騙し、意図していないクライアントにアクセス許可を与えさせようとする試みを防ぐべきです。

この認可フローは、次のシーケンス図で説明するのが最も分かりやすいでしょう。

Image

このフローでは、Access Token を取得するために、いくつかのステップを踏む必要があります。

  1. クライアントが、authorization server が提供する認可 UI にユーザーを誘導する
  2. authorization server がユーザーに同意画面(consent screen)を表示する
  3. ユーザーがクライアントのアクセスを承認し、authorization server がユーザーをクライアントへリダイレクトし、access code を付与する
  4. クライアントが access code を token 群と交換し、それらをローカルにキャッシュする
  5. クライアントが Access Token を用いて MCP server へアクセスする

しかし、このフローを開始できるようにするには、authorization server はまず、認可プロセスを開始するクライアントについての基本情報を必要とします。

  1. Client name: 同意画面に表示する、人間が読めるテキスト。ユーザーがアクセスを許可するか判断する助けとなる。
  2. Redirect URL: ユーザーが同意した場合に、authorization code を返す送信先。

悪意あるクライアントが、ユーザーを騙して意図しないアクセス許可を与えさせるのを防ぐために、authorization server は保持しているクライアント情報を信頼できなければなりません。

たとえば、悪意あるクライアントが同意画面で自分を Claude Desktop だと名乗りつつ、実際には Claude Desktop の開発者と無関係な人物が所有している、ということが起こりえます。ユーザーが同意画面のクライアント情報を見て、正当な Claude Desktop を認可しているつもりでアクセスを許可してしまうと、気づかないうちに悪意あるクライアントがそのアカウントへアクセスできるようになります。

Improving Client Registration in MCP

MCP のユーザーにとって一般的なパターンは、MCP client に MCP server の URL を直接入力して接続することです。

これは典型的な OAuth の認可パターンと逆向きです。通常はクライアント開発者が接続先の resource server を想定しますが、ここではユーザーが接続する resource server を選びます。さらに問題を複雑にしているのは、MCP server が使用しうる authorization server の数が無制限である点です。つまりクライアントは、どのプロバイダが使われていても認可フローを完遂できる必要があります。

一部のクライアント開発者は、少数の authorization server に対して事前登録(pre-registration)を実装しています。この場合、クライアントが既知の authorization server を検出したときには DCR に依存しなくて済みます。しかし、MCP エコシステムの広さを考えると、この解決策はスケールしません。すべてのクライアントを、存在しうるすべての authorization server に登録しておくことは不可能です。そこで、この課題を軽減するために、client registration 体験を改善するにあたって達成したい目標を整理しました。

  1. Clients: クライアント開発者は、MCP server が利用しうる各 authorization server ごとに pre-registration を実装し、client ID を配布する必要がないこと。
  2. Users: ユーザーは、事前登録プロセスを自分で行ったり、接続する MCP server ごとに client ID を手動で指定したりする必要がないこと。
  3. Authorization servers:
  • Trust in Metadata: authorization server が、クライアントに紐づける name や redirect URL といったメタデータを信頼できる方法があること。
  • Single Client ID per App: ガバナンスや管理の目的で、authorization server がクライアントごとに「アプリあたり 1 つ」の client ID を持てること。
  • Selective Allow/Deny: authorization server が、ポリシーに基づいてクライアントを選択的に許可/拒否できること。
  • Database Management: authorization server が、新しい client registration のたびに無制限のデータベースや有効期限管理フローを扱う必要がないこと。

現状、既存の client registration アプローチのどれも、これらすべての要件を満たしていません。pre-registration は(無制限のクライアントが無制限のサーバーへ接続しうる)変動の大きい環境では手間が大きすぎます。一方、DCR は手間を減らしますが、運用上の問題を生み、authorization server の多くがまだそれに対応できていません。

Two Distinct Challenges in MCP Client Registration

MCP server の実装者と広範に議論した結果、registration 問題に対する競合するいくつかの解決策は、次の 2 つの別々の課題に対処していることが分かりました。

  1. オープンな環境における Dynamic Client Registration の 運用上の制約
  2. さまざまなデプロイシナリオにおける クライアントの同一性と、なりすましのリスク

Challenge 1: Operational Limitations of Dynamic Client Registration

The DCR Model Mismatch

DCR の設計は、現代の OAuth ベースの authorization server で利用できる pre-registration パターンを API 経由でも利用できるようにしたものです。MCP のような完全にオープンな環境では、DCR はオープンな registration endpoint が導入する運用上の課題を強く浮き彫りにします。

authorization server にとって:

  • 無制限のデータベース増大: ユーザーがクライアントを MCP server に接続するたびに、(クライアントがすでに登録を持っていない限り)authorization server に新しい registration が作成されます。さらに registration は移植できないため、Windows のマシンで Claude Desktop を使い、その後 macOS の Claude Desktop に切り替えると、別々の client registration が 2 つ作られます。
  • クライアント失効の「ブラックホール」: client ID が無効であることをクライアントに伝える手段がありません(それをやると open redirect 脆弱性を作ってしまいます)。クライアントは client ID 管理のために独自のヒューリスティクスを実装しなければなりません。
  • インスタンス単位の混乱: 同じアプリケーションを使っていても、異なるマシンや異なるユーザーでは各クライアントインスタンスがそれぞれ client ID を持つのが一般的です。監査の観点では、authorization server の管理者は、同じアプリケーションのレコードが数百(場合によっては数千)並んでいるのを、理由も規則性もなく目にすることになります。
  • Denial-of-Service 脆弱性: 認証されていない /register endpoint は authorization server 内のデータベースに書き込みます。そのためテナント管理者は、レート制限やポリシー制御(例: クライアント登録を許可するホスト)を心配しなければなりません。

クライアントにとって:

  • 追加のオーバーヘッド: registration 状態の管理と、Access Token / Refresh Token 以外の secret 管理
  • 有効性チェック不可: client ID がまだ有効かどうかを検証できない
  • ライフサイクルが不明確: いつ再登録すべきか、いつ credential を更新すべきかの指針がない

Solution: Client ID Metadata Documents (CIMD)

Client ID Metadata Documents(CIMD)は、「OAuth Client ID Metadata Document」に記述され、Bluesky によって実装されており、これらの運用上の問題を見事に回避します。

registration というステップの代わりに、クライアントは HTTPS のメタデータ URL をそのまま client ID として用います。サーバーは認可時にその URL からメタデータを取得します。

Image

これにより、運用上の問題はすべて解決されます。

  • 無制限のデータベース増大がない: サーバーは必要に応じてメタデータを取得する(性能のためにキャッシュ可能)
  • 失効管理が不要: URL が ID であり、失効しない
  • 自然なアプリ単位モデル: ユーザー単位ではなく、アプリケーション単位で 1 URL
  • registration endpoint 不要: 認証なしの書き込み操作がなくなる

代償は何でしょうか。クライアントは HTTPS URL 上でメタデータドキュメントをホストする必要があります。Web application ならこれは簡単です。デスクトップアプリケーションの場合は、通常は Backend 側のインフラでホストすることになります。

Challenge 2: Client Identity and Impersonation

2 つ目の課題は DCR vs. CIMD の議論とは直交しています。これは、クライアントが「名乗っているとおりの存在」だと信頼できるか、という問題です。この問題は、registration プロセスをどう実装しても存在し続けます。

Web application のクライアントでは、信頼はより単純です。証明書認証局に紐づく HTTPS ドメインがあるからです。デスクトップクライアントの場合、既存の Backend インフラに認可処理をオフロードできないと、クライアントが正当で改変されていないことを信頼するのは難しくなります。

The Trust Spectrum

なりすましのシナリオは、攻撃者コストと、緩和策の複雑さという 2 つの軸で整理できます。

Image

攻撃者コスト低/緩和策の複雑さ低: ドメインベースの攻撃

  • 攻撃: 悪意ある callback URI を登録し、自分を Claude Desktop だと名乗る
  • コスト: ユーザーを騙してリンクをクリックさせ、同意させる
  • 緩和策:
    • 信頼できるドメイン/URL を制限する
    • 不明なドメインに対して警告を表示する
    • DCR と CIMD の両方で有効

攻撃者コスト中/緩和策の複雑さ中: localhost のなりすまし

  • 攻撃: localhost:8080 上で悪意あるアプリを動かし、正当なクライアントになりすます
  • コスト: ユーザーに悪意あるアプリを実行させる(さらに、そのアプリにデータアクセスの同意をさせる)
  • 問題: デスクトップアプリは secret を保持できず、同一性を証明するのが難しい

攻撃者コスト高/緩和策の複雑さ高: プラットフォームにより attested されたアプリケーション

  • 攻撃: 信頼された権威によって悪意あるクライアントに署名を得る
  • コスト: 極めて高い(認証ベンダーのプロセス侵害が必要)
  • 緩和策: プラットフォームのシステムレベルの attestation(将来の作業)

Solution: Software Statements for Desktop Applications

中間層のなりすましを幅広く解決し、さらに localhost のなりすましを防ぐためには、署名された software statements が必要です。これを実装するには、次が必要になります。

  1. クライアントが Backend 上で JSON Web Key Set(JWKS)をホストする
  2. クライアントが自前のフローでユーザーを認証する
  3. クライアントが所有する Backend service が、クライアントの同一性を証明する短命な署名付き JWT を発行する
  4. クライアントがこの JWT を OAuth 2.0 フローに含める
  5. authorization server が、信頼された JWKS に対して JWT を検証する

これにより、クライアントのなりすましのハードルは大きく上がります。攻撃者は次のいずれかを満たさなければならなくなるためです。

  • クライアントの Backend インフラを侵害する、または
  • クライアントの認証フローをうまくなりすます

重要なのは、software statements は DCR と CIMD の両方で機能するという点です。競合する解決策ではなく、補完的なセキュリティ層です。

Future: Platform-Level Attestation

最も強力な防御は、プラットフォームレベルの attestation です。たとえば macOS、Windows、Android が、そのソフトウェアが正当であることを保証する、といった仕組みです。

OS レベルの attestation があれば、クライアントのなりすましは不合理なほど高コストになります。これが software statement と具体的にどう結びつくかはまだプロトタイプ化されていませんが、大枠の方向性としては、プラットフォームレベルのアプリケーション同一性検証を OAuth 2.0 フローに通していくことになります。

The Complementary Path Forward

利用可能な選択肢を検討する一方で、重要なのは「解決策同士の二者択一ではない」という点です。私たちは、異なる問題に対して補完的なアプローチを探っています。

運用上の問題に対して: DCR よりも CIMD を優先して CIMD サポートを追加することを検討しています。

  • 後方互換性のために DCR は維持する
  • 新規実装には CIMD を推奨する
  • どちらも同じ認可の目的を達成する

信頼の問題に対して: software statements を上乗せする

  • DCR と CIMD の両方に対するオプションの強化
  • localhost のなりすましが懸念される場合にのみ必須
  • authorization server が必要な信頼レベルを選択する

Security Considerations

CIMD と software statements のどちらも、authorization server が(場合によっては信頼できないドメインに対して)アウトバウンドの HTTPS リクエストを行う必要があります。実装は次を行わなければなりません。

  • 内部ネットワークへのアクセスを遮断して SSRF 攻撃を防ぐ
  • タイムアウトとサイズ制限を実装する
  • 性能のためのキャッシュ戦略を検討する
  • レスポンス形式を厳密に検証する

これらのアプローチを採用するなら、脆弱性を避けつつ実装者が簡単に導入できるように、良いベストプラクティスと SDK サポートが必要になります。

Next Steps

これらのアプローチに関する議論は、Specification Enhancement Proposals(SEP)で行われています。

  • SEP-991: Client ID Metadata Documents
  • SEP-1032: Software Statements with DCR

参加方法: Discord(#auth-wg-client-registration チャンネル)で議論に加わるか、SEP に直接コメントしてください。

このブログ記事の作成に協力してくれた次の方々に大きな感謝を: Den Delimarsky、Aaron Parecki、Geoff Goodman、Andrew Block、Pieter Kasselman、Abhishek Hingnikar、そして Bobby Tiernay。