feat: MCP サーバ用 OAuth2 scope と firewall を追加#190
Open
dotani1111 wants to merge 11 commits into
Open
Conversation
dotani1111
commented
Jun 14, 2026
Contributor
- scopes.available に mcp:product:read / mcp:order:read / mcp:customer:read / mcp:plugin:read を追加 (本体同梱の MCP サーバ機能の領域別 read scope。 GraphQL の read/write とは名前空間 mcp: で分離)
- ApiExtension::prepend で ^//mcp 用の OAuth2 stateless firewall を admin の前に注入 (本体側 Tool の IsGranted と AND 評価で認可)
- ApiExtensionTest: firewall 順序 / shape / 既存 admin/customer の csrf_token_generator・anonymous 削除を検証
- scopes.available に mcp:product:read / mcp:order:read / mcp:customer:read / mcp:plugin:read を追加 (本体同梱の MCP サーバ機能の領域別 read scope。 GraphQL の read/write とは名前空間 mcp: で分離) - ApiExtension::prepend で ^/<admin>/mcp 用の OAuth2 stateless firewall を admin の前に注入 (本体側 Tool の IsGranted と AND 評価で認可) - ApiExtensionTest: firewall 順序 / shape / 既存 admin/customer の csrf_token_generator・anonymous 削除を検証 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
削除リンク生成に使う admin_api_oauth_delete の identifier 制約が \w+ で ハイフンを許さないため、 ハイフン入り client_id があると一覧の URL 生成で例外になる。 [\w-]+ に緩める。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MCP サーバは OAuth 自動探索メタデータを持たず、 店舗オーナーが自力でトークンを得る 手段が無かった。 league の AccessToken を再利用し、 管理画面で手動発行 (1 度だけ表示) する PAT 型の UX を追加する。 認証・失効は既存 firewall の経路にそのまま乗る。 - OAuth 管理画面を「API 新規追加 / MCP 新規追加」の 2 ボタンに分離 - MCP 発行: ラベル + MCP scope (mcp:*:read) + 有効期限 (30/90/180/365日) → JWT を 1 度表示 - 一覧に MCP トークンを表示し失効ボタンを追加 (revoke → 即 401) - 専用クライアント mcp_pat を PluginManager::enable で冪等生成し API 一覧からは除外 - 発行は scope/期限/発行者を防御的に検証し、 AccessToken model とメタを 1 トランザクションで 永続化してから署名する (途中失敗で失効不能な生トークンを残さない) - McpToken エンティティ (plg_api_mcp_token) で表示用メタ (ラベル/scope/期限/発行者) を保持 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 発行したトークンが /admin/mcp の firewall を通る (200) - 失効すると同じトークンで 401 - mcp:*:read 以外の scope / プリセット外の有効期限は発行できない (フォームバイパス防御) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
テストが redirectUris を持たない client を拾い league の検証で 400 になっていた。 setUp で redirectUris/scope を持つ confidential client を生成して使う。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
手動トークンに代わり、 クライアントが 401→メタデータ→動的登録→管理ログイン+同意→ トークン取得 を自動で行えるようにする。 手動トークン方式は併存。 - 401 の WWW-Authenticate に RFC 9728 の resource_metadata ポインタ (mcp firewall の entry_point) - GET /.well-known/oauth-protected-resource (RFC 9728) / oauth-authorization-server (RFC 8414) を公開 (Host 詐称によるキャッシュ汚染を避けるため no-store) - POST /register (RFC 7591 DCR): public client を作成。 redirect_uri は https/loopback のみ許可し、 パーサ差異 (parse_url vs WHATWG) による host 詐称 (\ / @ / fragment) を fail-closed で拒否。 grant=authorization_code+refresh_token・scope=mcp:*:read に固定、 IP+グローバルの 2 段レート制限、 save 失敗と拒否を監査ログに記録 - 公開ルートは実在 2 well-known と /register に完全一致で限定 (security:false) - 同意画面に MCP scope の説明文言を追加 (read/write と同様、 未翻訳キーの露出を解消) - メタデータ/WWW-Authenticate を OAuthMetadataBuilder で一元生成 (canonical resource URI を一致) - 本番は TRUSTED_HOSTS / TRUSTED_PROXIES の設定が前提 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .well-known 2 本が公開で正しい JSON を返す - /admin/mcp 401 が resource_metadata を広告する - DCR は loopback redirect を受理し scope/grant を MCP read に固定 - 外部 http redirect・パーサ差異 (バックスラッシュ) redirect は拒否 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
eccube:plugin:enable の時点では league の doctrine persistence が未配線で、 Model\Client のメタデータが解決できず enable が MappingException で失敗する。 クライアント生成を実行時 (初回トークン発行時) の冪等生成に移し、 enable は EC-CUBE エンティティのみ触るようにする。 grant=authorization_code・ scope=mcp:*:read 固定は維持。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- /admin/mcp (本体同梱の route _mcp_endpoint) を叩く統合テストは、 プラグイン単体 CI に MCP サーバが無く実行不能のため削除。 トークン受理/失効は本体 mcp ジョブの McpTokenRevocationContractTest、 401 の resource_metadata 広告は McpFirewallContractTest が担う - McpTokenControllerTest はプラグインが所有する発行ロジック (scope 限定・有効日数縛り) に絞る - mcp_oauth_public firewall 追加で変わった順序・公開条件 (security:false/完全一致) と mcp の entry_point を ApiExtensionTest の期待値に反映 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8633afd to
9649345
Compare
DCR (RFC 7591) で量産される放置クライアントを定期削除する。 - eccube:api:mcp:cleanup-dcr-clients [--days=30] [--dry-run]: 登録から grace 日数を 過ぎ、 有効な access/refresh トークンを持たない DCR client を削除 - league の oauth2_client に作成時刻が無いため、 grace 判定用の作成時刻を側テーブル plg_api_dcr_client (DcrClient) で追跡し、 DCR 登録成功時に記録する - 削除は 1 トランザクションで client と追跡レコードをまとめて消す (部分失敗での不整合を防ぐ)。 client の access token は FK ON DELETE CASCADE、 孤立する refresh は明示削除する - 掃除対象は追跡レコードのある client のみ (導入前/記録漏れは作成時刻が無く対象外) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mix-up 攻撃対策として、 認可応答 (oauth2_authorize の redirect) に発行元 issuer を示す iss パラメータを付ける。 league は認可コード応答にフックが無いため kernel.response で Location に後付けし、 issuer は AS メタデータと同一値 (OAuthMetadataBuilder::baseUrl) を使う。 - AuthorizationResponseIssListener: code/error を持つ認可 redirect にのみ iss を付与 (ログイン redirect 等は対象外) - メタデータの authorization_response_iss_parameter_supported を true 化 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.