-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Problem
Our mcp-auth crate (17,480 lines) implements a custom API key-based authentication system that is not compliant with the official MCP specification. The MCP spec mandates OAuth 2.1 with PKCE for HTTP transports.
What We Have (Non-Standard)
- ❌ Custom API key system (~3,150 lines: manager.rs + storage.rs)
- ❌ Custom JWT session tokens (1,374 lines)
- ❌ Custom auth extractors for HTTP/WebSocket/Stdio
- ✅ RBAC (permissions) - could map to OAuth scopes
- ✅ Transport abstractions - could be reused
What MCP Spec Requires
For HTTP Transports:
- ✅ OAuth 2.1 (draft-ietf-oauth-v2-1-13) with PKCE
- ✅ OAuth 2.0 Authorization Server Metadata (RFC 8414)
- ✅ Dynamic Client Registration (RFC 7591)
- ✅ Protected Resource Metadata (RFC 9728)
- ✅ Resource Parameter Binding (RFC 8707)
- ✅ Bearer token validation
- ✅ Proper scope management (progressive, least-privilege)
For Stdio Transports:
- ✅ Environment variable credential retrieval (we already have this)
Proposed Solution
Phase 1: Research & Design
- Evaluate Rust OAuth libraries:
oxide-auth- OAuth 2.0 server/clientoauth2crate - Client-side OAuth flows- Custom implementation vs. existing crates
- Design architecture:
- OAuth server endpoints (authorize, token, metadata)
- PKCE implementation
- Dynamic client registration
- Token validation middleware
- Map existing features to OAuth:
- RBAC permissions → OAuth scopes
- Sessions → OAuth refresh tokens
- API keys → Initial OAuth tokens (migration path)
Phase 2: Implement OAuth 2.1 Server
New modules to create:
mcp-auth/src/oauth/
├── mod.rs # Public API
├── server.rs # Authorization server
├── pkce.rs # PKCE verification
├── client_registry.rs # Dynamic client registration (RFC 7591)
├── token.rs # Token generation/validation
├── metadata.rs # Server metadata (RFC 8414)
├── resource.rs # Resource metadata (RFC 9728)
└── scopes.rs # Scope management
Estimated: ~2,500-3,500 lines
Phase 3: Delete/Replace Custom Auth
Delete:
manager.rsAPI key logic (~1,451 lines)storage.rsAPI key storage (~1,699 lines)- Custom auth extractors that don't use OAuth
Keep/Adapt:
jwt.rs- Use for OAuth token format (572 lines)session/- Use for refresh token sessions (802 lines)permissions/- Map to OAuth scopes (703 lines)transport/- Adapt for Bearer token extractionmiddleware/- Adapt for OAuth validation
Net change: -3,150 lines of API key code, +3,000 lines of OAuth code = ~0 net lines
Phase 4: Migration Path
For backward compatibility, we could:
- Dual mode: Support both API keys and OAuth temporarily
- Auto-migration: Convert existing API keys to OAuth clients
- Deprecation: Mark API key methods as
#[deprecated] - Remove: Delete API key code in next major version
Or aggressive approach:
- Delete API key code immediately
- Only support OAuth 2.1 going forward
- Breaking change for v1.0.0
Implementation Checklist
- Research Rust OAuth libraries (oxide-auth vs. oauth2 vs. custom)
- Design OAuth server architecture
- Implement PKCE (Proof Key for Code Exchange)
- Implement authorization endpoint
- Implement token endpoint
- Implement dynamic client registration (RFC 7591)
- Implement authorization server metadata endpoint (RFC 8414)
- Implement resource parameter binding (RFC 8707)
- Map RBAC permissions to OAuth scopes
- Update middleware for Bearer token validation
- Update transport extractors for OAuth
- Add OAuth examples and documentation
- Write integration tests against MCP spec
- Migration guide for existing API key users
- Delete API key system
Benefits
✅ MCP Spec Compliant - Works with standard MCP clients
✅ Industry Standard - OAuth 2.1 is well-understood and battle-tested
✅ Better Security - PKCE, dynamic registration, proper token validation
✅ Simpler - Remove 3,150 lines of custom API key code
✅ Interoperable - Can use standard OAuth tools and libraries
✅ Scalable - OAuth designed for distributed systems
Risks
Questions to Resolve
- Should we use an existing Rust OAuth library or implement from scratch?
- Do we support both API keys and OAuth during migration, or clean break?
- What's the migration timeline (immediate vs. gradual deprecation)?
- Should OAuth be optional feature or always-on for HTTP transports?
- Do we implement both OAuth server + client, or just server?
Related Issues
- 🚨 Critical: Refactor authentication architecture (30K LOC → 500 LOC) #64 - Refactor mcp-auth (Phases 1 & 2 complete, this is follow-up)
- feat(ui): add ergonomic UI helper methods for MCP Apps Extension #70 - UI helper methods
- refactor(mcp-auth): Phase 1 - Remove CLI tools and performance testing #71 - Phase 1 (CLI tools removal)
- refactor(mcp-auth): Phase 2 - Optional feature flags and dead code removal #72 - Phase 2 (Optional features)