🔏

MCPの認証について、理解したい。

に公開

目的

MCPが定める認証関連のことについて、理解した上で仕様を定められるようになりたい。

Anthropic公式からわかること

MCPを策定しているAnthropic公式サイトからわかることを列挙してみます。

https://modelcontextprotocol.io/specification/draft/basic/authorization

MCPではトランスポートレベルでの認可機能を提供しています。
サポートされている標準的なトランスポートはStreamable HTTP/stdioですが、認証の対象になるのは主にHTTPです。

Authorization is OPTIONAL for MCP implementations. When supported:
Implementations using an HTTP-based transport SHOULD conform to this specification.
Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.
Implementations using alternative transports MUST follow established security best practices for their protocol.

HTTPベースの場合にはSHOULD
STDIOの場合はNot SHOULD
その他のトランスポートの場合はプロトコルごとに定められたベストプラクティスに従うこと

とのことです。

大抵の場合、認証が必要になるのはリモートMCPサーバーを実装したい際なのでしょう。

OAuth

公式ではOAuth2.1に準拠した方法を推奨しています。
公式文にも認証関連の記載がありますが、別途公式ブログに詳細な解説が存在しています。

https://blog.modelcontextprotocol.io/posts/client_registration/?utm_source=chatgpt.com

OAuth2.1

OAuth2.0から進化した2.1な訳ですが、変更点を把握しておきたいと思います。
公式サイトでは以下のように記載があります。

PKCE is required for all OAuth clients using the authorization code flow
Redirect URIs must be compared using exact string matching
The Implicit grant (response_type=token) is omitted from this specification
The Resource Owner Password Credentials grant is omitted from this specification
Bearer token usage omits the use of bearer tokens in the query string of URIs
Refresh tokens for public clients must either be sender-constrained or one-time use
The definitions of public and confidential clients have been simplified to only refer to whether the client has credentials

https://oauth.net/2.1/

詳細を解説することはしませんが、OAuth2.0に見られた脆弱性を解消する意図が見られます。
MCPではOAuth2.0を用いた実装が可能ですが、可能な限り2.1に準拠するべきだと思われます。

認証フロー

ここからがわかりにくかった箇所です。
MCPがどのように認証を行っているのか、眺めてみます。

  1. クライアントは、認可サーバーが提供する認可UIにユーザーを誘導
  2. 認可サーバーはユーザーに同意画面を表示する
  3. ユーザーがクライアントのアクセスを承認し、認可サーバーはアクセスコードを使用してユーザーをクライアントにリダイレクトする
  4. クライアントはアクセスコードをトークンのセットと交換し、トークンはローカルにキャッシュ
  5. クライアントはアクセストークンを使用してMCPサーバーにアクセスする

これは通常のOAuth2.0/2.1のシーケンス図です。
重要になってくるのは、MCPクライアントが起動し、サーバーとのInitializeを行う際に、どこのタイミングで認証が走るのかについてです。

MCPサーバー・クライアントの認証

まずは全体像を見てみましょう。

https://modelcontextprotocol.io/specification/draft/basic/authorization

わかりにくいのでGPTに日本語に直してもらいます。

分解

なんとなく見えてきましたので、分解してみていきましょう。
まずは初回アクセスのシーンです。

クライアント側からの視点だと、最初はMCPサーバーへのアクセスに認証が必要がどうかが不明です。
まずは認証トークンなしでアクセスします。

認証できなかった場合に401が返ってきます。
ヘッダーにメタデータが入っている場合にはシンプルです。
GET メタデータURLののちに、AuthのURLを取得します。

メタデータが存在しない場合にはエラーハンドリングが行われます。(詳細割愛)

先述の通り、OAuth処理が走ります。

疑問の解消

自分がわかっていなかった点は以下の通りです。

  • MCPサーバーとAuthサーバーは同じ必要があるのか
  • Authサーバーの場所はいつ知ることになるのか

自前のMCPサーバーでも、GoogleOAuthやDiscordOAuthの使用が可能なようですね。

まとめ

リモートMCPサーバーを構築する場合にはOAuthが必要とのことで、気になっていた部分は解消することができました。
現在の主流はローカルMCPサーバーですが、エッジLLMなどの環境においては必須になることがあるかもしれません。

Discussion