-
Notifications
You must be signed in to change notification settings - Fork 615
[FEATURE][AUTH]: Infer identity provider info for onboarded MCP servers #1435
Description
🧭 Epic
Title: Infer Identity Provider Information for Onboarded MCP Servers
Goal: Automatically discover OAuth 2.0 Authorization Server metadata (RFC 8414) for MCP servers, enabling seamless authentication without manual configuration of issuer URLs and endpoints.
Why now:
- Onboarding MCP servers requires manual configuration of OAuth endpoints
- RFC 8414 provides a standard way to discover authorization server metadata
- Reduces friction when connecting to OAuth-protected MCP servers
- Enables Dynamic Client Registration (RFC 7591) for automated client setup
- Current codebase has foundation in
dcr_service.pybut needs broader integration
📖 User Stories
US-1: Developer - Auto-Discover OAuth Endpoints
As a: Developer onboarding an OAuth-protected MCP server
I want: The gateway to automatically discover the authorization server's endpoints
So that: I don't need to manually configure token endpoint, authorization endpoint, etc.
Acceptance Criteria:
Scenario: Discover AS metadata from issuer URL
Given an MCP server protected by OAuth with issuer "https://auth.example.com"
When I register the gateway with the issuer URL
Then the gateway should fetch /.well-known/oauth-authorization-server
And automatically populate token_endpoint, authorization_endpoint, jwks_uri
And store the discovered metadata for future use
Scenario: Fallback to OIDC discovery
Given an OAuth server that doesn't support RFC 8414
When RFC 8414 discovery fails
Then the gateway should try /.well-known/openid-configuration
And use OIDC metadata if available
Scenario: Handle discovery failure gracefully
Given an OAuth server with no discovery endpoints
When both RFC 8414 and OIDC discovery fail
Then the gateway should prompt for manual endpoint configuration
And log the discovery failure for debuggingTechnical Requirements:
- Use existing
DCRService.discover_as_metadata()frommcpgateway/services/dcr_service.py - Cache discovered metadata with configurable TTL
- Support both RFC 8414 and OIDC discovery paths
US-2: Admin - Dynamic Client Registration
As a: Platform Administrator
I want: The gateway to automatically register as an OAuth client when DCR is supported
So that: I don't need to manually create OAuth applications in the identity provider
Acceptance Criteria:
Scenario: Auto-register via DCR
Given an authorization server supports Dynamic Client Registration
When I configure a new gateway with OAuth authentication
Then the gateway should check if registration_endpoint is available
And automatically register using DCR if supported
And store the client_id and client_secret securely
Scenario: Manual client setup when DCR unavailable
Given an authorization server doesn't support DCR
When I configure a new gateway with OAuth
Then the gateway should prompt for client_id and client_secret
And provide instructions for manual OAuth app setup
And validate the credentials before saving
Scenario: DCR with initial access token
Given an authorization server requires authentication for DCR
When I have an initial_access_token
Then the gateway should use it to register the client
And handle token expiration gracefullyTechnical Requirements:
- Check for
registration_endpointin AS metadata - Implement RFC 7591 client registration request
- Support initial_access_token for protected registration
- Store credentials encrypted in database
US-3: Operator - Cache and Refresh Metadata
As a: Platform Operator
I want: Discovered metadata cached with automatic refresh
So that: The gateway doesn't make discovery requests on every auth operation
Acceptance Criteria:
Scenario: Metadata is cached
Given I have discovered AS metadata for "https://auth.example.com"
When I make multiple OAuth requests
Then the cached metadata should be used
And no additional discovery requests should be made
Scenario: Metadata refresh on expiry
Given cached metadata has expired (TTL exceeded)
When an OAuth operation is performed
Then the metadata should be re-discovered
And the cache should be updated with new metadata
Scenario: Handle metadata changes
Given the authorization server's endpoints change
When the cached metadata is refreshed
Then the new endpoints should be used
And connections using old endpoints should fail gracefullyTechnical Requirements:
- Use existing
_metadata_cacheindcr_service.py - Configurable TTL via
DCR_METADATA_CACHE_TTL(default: 3600s) - Background refresh before expiry
🏗 Architecture
Discovery Flow
sequenceDiagram
participant Admin as Admin UI
participant Gateway as MCP Gateway
participant DCR as DCR Service
participant Cache as Metadata Cache
participant AS as Authorization Server
Admin->>Gateway: Register MCP server (issuer URL)
Gateway->>DCR: discover_as_metadata(issuer)
DCR->>Cache: Check cache for issuer
alt Cache hit
Cache-->>DCR: Return cached metadata
else Cache miss
DCR->>AS: GET /.well-known/oauth-authorization-server
alt RFC 8414 supported
AS-->>DCR: AS metadata
else RFC 8414 not supported
DCR->>AS: GET /.well-known/openid-configuration
AS-->>DCR: OIDC metadata
end
DCR->>Cache: Store metadata (TTL)
end
DCR-->>Gateway: AS metadata
alt DCR supported
Gateway->>DCR: register_client(metadata)
DCR->>AS: POST /register
AS-->>DCR: client_id, client_secret
Gateway->>Gateway: Store credentials (encrypted)
else DCR not supported
Gateway->>Admin: Prompt for credentials
end
Metadata Storage
classDiagram
class ASMetadata {
+issuer: str
+authorization_endpoint: str
+token_endpoint: str
+registration_endpoint: Optional[str]
+jwks_uri: str
+scopes_supported: list[str]
+grant_types_supported: list[str]
+discovered_at: datetime
+expires_at: datetime
}
class OAuthCredentials {
+gateway_id: str
+client_id: str
+client_secret_encrypted: str
+scopes: list[str]
+registered_via: str
+created_at: datetime
}
📋 Implementation Tasks
Phase 1: Discovery Enhancement
- Extend
DCRService.discover_as_metadata()to return typedASMetadataobject - Add automatic fallback from RFC 8414 to OIDC discovery
- Add comprehensive error handling with specific error types
- Log discovery attempts and failures for debugging
Phase 2: Cache Management
- Make metadata cache TTL configurable via
DCR_METADATA_CACHE_TTL - Add background refresh before expiry (proactive refresh)
- Add cache invalidation endpoint for admin use
- Add metrics for cache hits/misses
Phase 3: Gateway Integration
- Auto-trigger discovery when registering OAuth-protected gateway
- Populate gateway OAuth config from discovered metadata
- Store discovered endpoints in gateway record
- Update Admin UI to show discovered vs manual endpoints
Phase 4: Dynamic Client Registration
- Implement RFC 7591 client registration in
DCRService - Support initial_access_token for protected registration
- Store client credentials encrypted in database
- Handle registration errors gracefully
Phase 5: Admin UI Updates
- Add "Discover" button in gateway OAuth configuration
- Show discovered endpoints (read-only)
- Prompt for credentials when DCR unavailable
- Show DCR status indicator
Phase 6: Testing
- Unit tests for RFC 8414 discovery
- Unit tests for OIDC fallback
- Unit tests for DCR registration
- Integration tests with Keycloak
- Integration tests with Auth0
- Integration tests with Azure AD
⚙️ Configuration Examples
Environment Variables
# OAuth Discovery (RFC 8414)
OAUTH_DISCOVERY_ENABLED=true
DCR_METADATA_CACHE_TTL=3600 # Cache TTL in seconds
# DCR Settings
DCR_ENABLED=true
DCR_DEFAULT_SCOPES="openid profile email"Gateway with Auto-Discovery
{
"name": "OAuth Protected MCP Server",
"url": "https://mcp.example.com/sse",
"authentication": {
"type": "oauth2",
"issuer": "https://auth.example.com",
"auto_discover": true
}
}Discovered Metadata (stored)
{
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"registration_endpoint": "https://auth.example.com/register",
"jwks_uri": "https://auth.example.com/.well-known/jwks.json",
"scopes_supported": ["openid", "profile", "email", "mcp:tools"],
"grant_types_supported": ["authorization_code", "client_credentials"],
"discovered_at": "2026-01-25T12:00:00Z",
"expires_at": "2026-01-25T13:00:00Z"
}✅ Success Criteria
- RFC 8414 discovery works for standard OAuth servers
- OIDC fallback works when RFC 8414 not supported
- Metadata cached with configurable TTL
- DCR registration works when supported
- Admin UI prompts for credentials when DCR unavailable
- Credentials stored encrypted in database
- Works with Keycloak, Auth0, Azure AD, Okta
- Graceful error handling for all failure modes
🏁 Definition of Done
- RFC 8414 discovery implemented in DCRService
- OIDC discovery fallback implemented
- Metadata caching with configurable TTL
- DCR registration (RFC 7591) implemented
- Gateway OAuth config auto-populated from discovery
- Admin UI updated with discovery features
- Credentials stored encrypted
- Unit tests for all discovery paths
- Integration tests with major IdPs
- Documentation updated
- Code passes
make verify - PR reviewed and approved
🔗 Related Issues
- [FEATURE][AUTH]: Propagate end user identity and context through the CF workflow #1436 - Propagate end user identity (uses token endpoints)
- [FEATURE][PLUGIN]: Enhance the IAM pre-tool plugin #1438 - IAM plugin enhancements
- OAuth Manager service
- DCR Service (
mcpgateway/services/dcr_service.py)
📓 Additional Context
Existing Codebase Support
The foundation for RFC 8414 discovery already exists in mcpgateway/services/dcr_service.py:
discover_as_metadata()method_metadata_cachefor caching- Configuration via
DCR_METADATA_CACHE_TTL
This feature extends the existing implementation for broader gateway integration.
Standards References
- RFC 8414 - OAuth 2.0 Authorization Server Metadata
- RFC 7591 - Dynamic Client Registration Protocol
- OpenID Connect Discovery