MCP の便利さを感じる一方、セキュリティに不安を感じる方もいるのではないでしょうか。例えば、公式で提供されている PostgreSQL の MCP では user/password が素のテキストで Config ファイルに記載されていますし、GitHub の MCP でも input
で入力受付が可能な VSCode 以外はアクセストークンが Config ファイルに平書きされています。環境変数を使った回避方法もありますが、様々なツールを扱う Config ファイルが誤って Commit などされた場合のダメージは計り知れないものがあります。
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
}
}
}
MCP Specification の 2025-03-26
版 では、待望の Authorization について仕様が追加されました。本記事では、その内容と実装のアプローチをお伝えします。なお、可能な限り正確に書くよう努めていますが著者はセキュリティの専門家ではないため、もし記載内容に不備や曖昧な点があればコメントを頂ければ幸いです。
以下に要点をまとめます。
-
MCP の Authorization には OAuth が採用された :
2025-03-26
版での Authorization は、OAuth 2.1/2.0 をベースにしています。これにより MCP Server 個別に利用可能な機能範囲を許可できます (GitHub なら、Server A には Private Repository へのアクセスを許可するけど B にはしないなど)。OAuth 2.1 ではクライアント固有の id である code verifier をアクセストークン発行時に認可サーバー側で検証をする PKCE (Proof Key for Code Exchange) が必須となっています。これにより悪意ある MCP サーバーのインストールで認可コードが奪取された場合の被害を一定防ぐことが出来ます。野良の MCP をふらっとインストールする機会は不正なモバイルアプリ等をインストールする機会より多いと考えられ、その意味で安全な対策が取られています - MCP Server ごとに認証・認可する課題が残る : OAuth は認可の仕様であり、アプリケーションごとに行う必要があります。一度「認証」したユーザーに MCP Server A, B, C の利用を許可するといった Single Sign On (SSO) のような体験を実現するには認証の仕組みである OpenID Connect など補完的な仕組みが不可欠です。こうした仕様は今後検討されると思われます
-
MCP Authorization の実装はこれから : 理由として、仕様自体がまだ不確定なためです。
2025-03-26
版で初めて策定され、落ち着くには一定時間がかかる理解です。ベースとしている OAuth 2.1 自体が本記事執筆時点でまだ確定していなかったり、追加される仕様もそれなりにあると思われます。特に、2025/5 時点で draft に記載されている Protected Resource Metadata (RFC9728) は Agent が MCP Server に必要な認証・認可プロセスを始めるのに不可欠な仕様です。こうした状況のためライブラリやサポートしている Managed も少ないのが現状です
以降のセクションでは、上記 3 点をより深く理解するための技術的背景と現時点の実装について記載します。MCP の登場により HTTP 世界の基礎的な理解が改めて問われている印象があり、今一度学び直す良いタイミングが来ていると思います。私が調べられる限りでまとめた内容や参考文献を書いていますので、お役に立てば幸いです!
OAuth 2.1 による MCP Server の認可プロセス
2025-03-26
版の Authorization にそって、MCP Server に対し GitHub / Google など外部リソースにアクセスする認可を与えるプロセスを示します。2.2 Example: authorization code grant に認可のフローがありますが、本文中で言及がある通り MCP Server 自身で認可を行っているため下記ではより一般的な外部認可 (Google や GitHub) を想定したフローを記載しています。
OAuth による認可は下記記事がとても分かりやすいです。ただ、OAuth 2.1 では PKCE が必須となりインプリシットフロー、リソースオーナー・パスワード・クレデンシャルズフロー (ROPC) が削除されます (参考)。
OAuth 2.1 の主な変更点は次の通りです
- PKCE の標準化 : PKCE ではクライアント側で一意にもつキー (code verifier) で認証を行いアクセストークン発行時にこのキーを必須とすることで (
Token Request with code + code_verifer
の箇所) 認可コードが URL 等から奪取されてもアクセストークン発行を防止する効果があります - インプリシットフローの削除 : インプリシットフローでは、認可コードでなくアクセストークンを直接発行するため、Callback URL でさらされるアクセストークンを奪取された場合たやすく不正な利用につながるため危険です
- ROPC の削除 : ROPC では OAuth の根幹でもあるアプリケーションからの認証・認可の委譲に反してユーザー自身の id/password を直接扱ってしまうため、奪取された場合の被害は有効期間のあるトークンの比ではないリスクがあります
この他、認可後のリダイレクト先の exact match や Query String でトークンをさらすことの禁止、トークンのリフレッシュの推奨が含まれる予定です。これらは、1) 不正なリダイレクト先の用意 2) (HTTPS でも) 素面でさらされる Query Parameters からの認可コード奪取、といったケースに対応するための措置です。
OAuth 2.1 はセキュリティの強化に加え脆弱性あるフローの削除を行っており、仕様の複雑化を押さえながらよりセキュアな方向に進化していると思います。
OAuth の課題 : OpenID Connect の生まれた背景
OAuth の関心はアプリケーション個別の適切な認可であり、途中の認証はそのための手段になります。フォーカスが "アプリケーション個別" であるため、一度の「認証」で複数のアプリケーションへのアクセスを許可する Single Sign On (SSO) 体験を OAuth の枠組みで提供するのは困難です。OAuth を拡張し認証のプロセス・認証情報を得るためのスコープなどを共通化し SSO 体験の実現を図るための枠組みが OpenID Connect になります。
Okta : "OpenID Connect、OAuth、SAMLの違いと用途とは?" より引用
OpenID Connect は認証によりユーザー情報が含まれた (JWT で暗号化された) ID Token を得るプロセスになります。仕組みは OAuth にのっとっていますが、ID Token は OAuth で扱う認可コード / アクセストークンいずれとも異なる別個の Token になります。そのため MCP Server ごとに認証をする必要がなくなっても、認可を個別にする必要は継続します。Gmail と GitHub でそもそも定義しているスコープが全然違うように、認可は認証に比べ共通・効率化が難しいことも事実です。
Agentic な世界に不可欠な仕様 : Protected Resource Metadata (RFC9728)
2025/5 時点で MCP Authorization の draft に入っている Protected Resource Metadata (PRM)(RFC9728) は、まさに認可の効率化を実現する仕様です。PRM は、文字通り Protect された resource
(API など) を扱うためにどんな authorization_servers
からどんな scopes_supported
の認可を受けてくればいいのか情報を提供します。
- 認可サーバーのエンドポイント等、OAuth のプロセスを始めるための情報は別途 RFC8414 で定義される OAuth 2.0 Authorization Server Metadata から得ることが出来ます。ただ、認可サーバーで OAuth のプロセスを行うには事前にアプリケーションを識別するためのクライアント登録が必要で、Agent (MCP Client) がいきなりプロセスを開始することはできません
- MCP Client が事前に必要な認可サーバーを全部把握するのは無理でしょ、という問題を解決するのが RFC 7591 で定義される Dynamic Client Registration Metadata です。先ほどの Authorization Server Metadata に含まれる
registration_endpoint
からクライアントの登録を行うことで認可を開始します
いろんな RFC が出てきたので、RFC の名前込みで MCP の Authorization の流れをまとめてみます。
MCP Specification の 2025-03-26
版では Authorization の仕様に RFC8414 と RFC7591 が既に含まれています。PRM (RFC9728) が含まれなかったのは RFC9728 の発行が 2025/4 で 3 月の仕様発行に間に合わなかったからだと思われます。次の版では多分確実に含まれて、これで Agent による自律的な MCP Server の認可ができるようになるはずです。
AWS での実装
draft 中の PRM を Dave Patten さんが AWS で実装されていた!ので紹介します。
こちらの記事では認可サーバーとして Amazon Cognito を使用しており、PRM の仕様を実装した MCP Server (Express.js) からメタデータをクライアントに提供しています。さらに素晴らしいことに、Cognito がまだ対応していない Dynamic Client Registration を AWS Lambda で実装されています。
- MCP Server にアクセスした際、Unauthorized であれば PRM を返す
- PRM から Authorization Server を特定し、認可を開始するためのエンドポイント情報などが含まれる Authorization Server Metadata を取得
- 本来は Metadata 取得の URL にアクセスするが、Cognito では提供していないので Cognito の情報を基に Client 側で組み立てている : Authorization Server Metadata の実装 (
authServerMetadata
)
- 本来は Metadata 取得の URL にアクセスするが、Cognito では提供していないので Cognito の情報を基に Client 側で組み立てている : Authorization Server Metadata の実装 (
- Cognito による PKCE を使用した OAuth を実施
- OAuth の実装 (
initiateAuthFlow
) - OAuth 2.1 で推奨となっている Refresh Token も実装されていました
- OAuth の実装 (
- Access Token を利用した MCP Server との通信を開始
GitHub で実装を公開いただいているので、ぜひ参考ください。MCP Server 自体はサーバーレスな AWS Lambda でも理論上は実装可能だと思います。
こちらの実装では Express の Middleware 機能を使用して認証部分をきれいに書いています。
おわりに
今回は MCP の仕様に Authorization が加わったことをきっかけに、背景となる OAuth の仕組みを深堀してみました。安全な MCP への第一歩となれば幸いです!