Skip to content

Conversation

@asoorm
Copy link
Contributor

@asoorm asoorm commented Jan 2, 2026

Implements OAuth 2.1 authorization for the MCP server with JWT validation and RFC 9728 Protected Resource Metadata support.

Problem

MCP server forwarded Authorization headers without validation:

  • No token validation or scope enforcement
  • All authenticated clients could execute any operation
  • Cannot integrate with enterprise auth servers (Keycloak, Auth0, Okta)
  • Non-compliant with MCP spec OAuth 2.1 requirements

Changes

  1. JWT Token Validation
  • Reuses router's JWKS-based validation infrastructure
  • Supports multiple JWKS providers with automatic key refresh
  • Validates tokens before processing any MCP requests
  1. HTTP-Level Authentication
  • Authentication enforced at HTTP middleware level (per MCP spec)
  • Returns 401 Unauthorized with WWW-Authenticate header on failures
  • Claims propagated to tool handlers via context
  1. RFC 9728 Metadata Endpoint
  • Public discovery at /.well-known/oauth-protected-resource
  • Enables clients to discover authorization server and required scopes
  1. Backward Compatible
  • OAuth disabled by default
  • No breaking changes to existing deployments

Configuration Example

mcp:
  enabled: true
  server:
    listen_addr: "0.0.0.0:5025"
    base_url: "https://mcp.example.com"
  oauth:
    enabled: true
    authorization_server_url: "https://auth.example.com"
    scopes: ["mcp:read", "mcp:write"]
    jwks:
      - url: "https://auth.example.com/.well-known/jwks.json"
        refresh_interval: 1h
        algorithms: ["RS256"]

asoorm added 10 commits January 1, 2026 20:48
Pass OAuth configuration to MCP server when enabled, fixing authentication
middleware that was never being triggered due to missing config.
- Add authorization_server_url to MCPOAuthConfiguration
- Implement /.well-known/oauth-protected-resource endpoint
- Add server base_url configuration for OAuth discovery
- Update auth middleware to include resource metadata URL in errors
- Update JSON schema with new OAuth discovery fields

This enables MCP clients to automatically discover OAuth endpoints
and complete authentication flows per MCP specification.
- Add HTTPMiddleware to authenticate all MCP requests
- Return 401 with WWW-Authenticate header per RFC 9728
- Update tests for new error messages
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the router label Jan 2, 2026
@asoorm asoorm changed the title feat(mcp): Add OAuth 2.1 authorization with JWT validation and RFC 9728 metadata add OAuth 2.1 authorization with JWT validation and RFC 9728 metadata Jan 2, 2026
@github-actions
Copy link

github-actions bot commented Jan 2, 2026

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-541f4824ff67efd616e5fb1350aeb62a35b9b691

@codecov
Copy link

codecov bot commented Jan 2, 2026

Codecov Report

❌ Patch coverage is 0% with 229 lines in your changes missing coverage. Please review.
✅ Project coverage is 31.82%. Comparing base (98bb8e9) to head (84495cd).

Files with missing lines Patch % Lines
router/pkg/mcpserver/server.go 0.00% 141 Missing ⚠️
router/pkg/mcpserver/auth_middleware.go 0.00% 83 Missing ⚠️
router/core/router.go 0.00% 4 Missing ⚠️
router/pkg/mcpserver/schema_compiler.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2438       +/-   ##
===========================================
- Coverage   62.75%   31.82%   -30.94%     
===========================================
  Files         296      213       -83     
  Lines       41353    23426    -17927     
  Branches     4244        0     -4244     
===========================================
- Hits        25951     7455    -18496     
+ Misses      15381    15043      -338     
- Partials       21      928      +907     
Files with missing lines Coverage Δ
router/pkg/config/config.go 10.38% <ø> (ø)
router/pkg/mcpserver/operation_manager.go 0.00% <ø> (ø)
router/pkg/mcpserver/schema_compiler.go 0.00% <0.00%> (ø)
router/core/router.go 40.63% <0.00%> (ø)
router/pkg/mcpserver/auth_middleware.go 0.00% <0.00%> (ø)
router/pkg/mcpserver/server.go 0.00% <0.00%> (ø)

... and 503 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@asoorm asoorm force-pushed the ahmet/eng-8386-implement-oauth-21-authorization-and-protected-resource branch from 9163735 to 84495cd Compare January 2, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants