-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
๐ Implement OAuth 2.1 Compliance for 2025 MCP Security Standards
Problem Statement
The current authentication system uses custom API keys instead of the official 2025 MCP security standards:
Current Issues:
- Custom API key system (not standards-compliant)
- Static token-based authentication
- No OAuth 2.1 support as required by MCP 2025 specification
- Token passthrough vulnerabilities possible
- Non-compliant with latest MCP security guidelines
Standards Gap:
- MCP 2025 mandates OAuth 2.1 for secure authorization
- PKCE (Proof Key for Code Exchange) is required for all clients
- Dynamic token validation with proper audience verification
- Modern security capabilities from OAuth 2.1 ecosystem
Motivation
Official MCP 2025 Requirements
From MCP Security Research:
"In March 2025, the MCP specification took a major leap forward with the release of a new specification that standardizes Authorization using OAuth 2.1"
Key Requirements:
- OAuth 2.1 compliance is mandatory for production deployments
- PKCE support raises security baseline significantly
- Token audience validation prevents unauthorized usage
- Identity provider integration for enterprise deployments
Security Benefits
- Eliminate token passthrough vulnerabilities
- Dynamic token validation vs static API keys
- Enterprise identity provider integration (Azure AD, Okta, Keycloak)
- MFA support through identity providers
- Audit compliance with standard protocols
Competitive Requirements
- Official MCP servers will require OAuth 2.1 compliance
- Enterprise adoption blocked without standards compliance
- Framework credibility depends on following official specifications
Solution Design
1. OAuth 2.1 Core Implementation
pub struct OAuth21Config {
pub client_id: String,
pub client_secret: Option<String>, // Optional for PKCE
pub authorization_server: String,
pub token_endpoint: String,
pub jwks_uri: String,
pub audience: String,
pub scopes: Vec<String>,
pub pkce_required: bool,
}
pub struct OAuth21Middleware {
config: OAuth21Config,
jwks_client: JwksClient,
token_validator: TokenValidator,
}2. PKCE Implementation
#[derive(Debug, Clone)]
pub struct PkceChallenge {
pub code_verifier: String,
pub code_challenge: String,
pub code_challenge_method: String, // S256
}
impl PkceChallenge {
pub fn new() -> Self {
let code_verifier = generate_secure_random(128);
let code_challenge = base64_url_encode(sha256(code_verifier.as_bytes()));
Self {
code_verifier,
code_challenge,
code_challenge_method: "S256".to_string(),
}
}
}3. Token Validation
#[async_trait]
impl AuthenticationMiddleware for OAuth21Middleware {
async fn authenticate(&self, request: &Request) -> Result<AuthContext, AuthError> {
// Extract Bearer token
let token = self.extract_bearer_token(request)?;
// Validate token with JWKS
let claims = self.token_validator.validate_token(&token).await?;
// Verify audience (critical for MCP compliance)
if !claims.audience.contains(&self.config.audience) {
return Err(AuthError::InvalidAudience);
}
// Verify issuer
if claims.issuer != self.config.authorization_server {
return Err(AuthError::InvalidIssuer);
}
// Create auth context
Ok(AuthContext {
user_id: claims.subject,
scopes: claims.scopes,
token_claims: claims,
authenticated_at: Utc::now(),
})
}
}4. Identity Provider Integration
pub enum IdentityProvider {
Keycloak(KeycloakConfig),
AzureAD(AzureADConfig),
Okta(OktaConfig),
Custom(CustomOAuth21Config),
}
impl IdentityProvider {
pub async fn discover_endpoints(&self) -> Result<OAuth21Config, DiscoveryError> {
match self {
IdentityProvider::Keycloak(config) => {
let discovery_url = format!("{}/auth/realms/{}/.well-known/openid_configuration",
config.base_url, config.realm);
self.fetch_discovery(&discovery_url).await
}
IdentityProvider::AzureAD(config) => {
let discovery_url = format!("https://login.microsoftonline.com/{}/v2.0/.well-known/openid_configuration",
config.tenant_id);
self.fetch_discovery(&discovery_url).await
}
// ... other providers
}
}
}5. Device Flow Support (Local Development)
// For stdio transport and local development
pub struct DeviceFlowAuth {
config: OAuth21Config,
}
impl DeviceFlowAuth {
pub async fn start_device_flow(&self) -> Result<DeviceFlowResponse, AuthError> {
let response: DeviceFlowResponse = self.client
.post(&format!("{}/device", self.config.token_endpoint))
.form(&[
("client_id", &self.config.client_id),
("scope", &self.config.scopes.join(" ")),
])
.send()
.await?
.json()
.await?;
println!("Visit: {} and enter code: {}",
response.verification_uri,
response.user_code);
Ok(response)
}
}Implementation Plan
Phase 1: OAuth 2.1 Core (Week 1)
- Create
pulseengine-mcp-oauth21crate - Implement JWT token validation with JWKS
- Add PKCE challenge/verify logic
- Create basic OAuth 2.1 middleware
- Add comprehensive error handling
Phase 2: Identity Provider Integration (Week 2)
- Implement Keycloak integration with discovery
- Add Azure AD support for enterprise
- Create Okta integration
- Add generic OpenID Connect provider support
- Implement endpoint discovery automation
Phase 3: Device Flow & Development (Week 3)
- Implement OAuth 2.1 device flow for local development
- Add stdio transport authentication
- Create development-friendly configuration
- Add token caching and refresh logic
- Implement graceful degradation for development
Phase 4: Production Integration (Week 4)
- Integrate with existing security middleware
- Add migration path from API key system
- Create configuration examples for common scenarios
- Add comprehensive testing and security audit
- Create deployment documentation
Configuration Examples
Environment-Based Setup
# OAuth 2.1 Configuration
MCP_OAUTH21_CLIENT_ID=mcp-server-client
MCP_OAUTH21_CLIENT_SECRET=your-secret-here
MCP_OAUTH21_ISSUER=https://auth.mycompany.com
MCP_OAUTH21_AUDIENCE=mcp://my-server
MCP_OAUTH21_SCOPES=mcp:read,mcp:write
# Identity Provider (Auto-discovery)
MCP_IDENTITY_PROVIDER=keycloak
MCP_KEYCLOAK_BASE_URL=https://auth.mycompany.com
MCP_KEYCLOAK_REALM=mcp-realm
# Development Mode (Device Flow)
MCP_DEV_MODE=true # Enables device flow for local developmentProgrammatic Configuration
use pulseengine_mcp_oauth21::*;
#[mcp_server(
name = "OAuth21 Server",
auth_provider = "oauth21"
)]
struct OAuth21Server;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let oauth_config = OAuth21Config {
client_id: env::var("MCP_OAUTH21_CLIENT_ID")?,
client_secret: env::var("MCP_OAUTH21_CLIENT_SECRET").ok(),
authorization_server: env::var("MCP_OAUTH21_ISSUER")?,
audience: env::var("MCP_OAUTH21_AUDIENCE")?,
scopes: vec!["mcp:read".to_string(), "mcp:write".to_string()],
pkce_required: true,
};
let mut server = OAuth21Server::with_oauth21(oauth_config).await?;
server.run().await?;
Ok(())
}Enterprise Keycloak Example
let identity_provider = IdentityProvider::Keycloak(KeycloakConfig {
base_url: "https://auth.enterprise.com".to_string(),
realm: "mcp-production".to_string(),
client_id: "mcp-server".to_string(),
});
let oauth_config = identity_provider.discover_endpoints().await?;
let server = McpServer::with_oauth21(oauth_config).await?;Acceptance Criteria
Standards Compliance
- Full OAuth 2.1 specification compliance
- PKCE implementation passes RFC 7636 tests
- JWT validation follows RFC 7519 standards
- Token audience validation per MCP 2025 requirements
- OpenID Connect discovery protocol support
Security Requirements
- No token passthrough vulnerabilities
- Secure random generation for PKCE challenges
- Proper JWT signature validation with JWKS
- Token expiration and refresh handling
- Secure credential storage and handling
Integration Requirements
- Works with major identity providers (Keycloak, Azure AD, Okta)
- Backward compatibility with existing API key system
- Device flow support for local development
- Environment variable configuration
- Migration tooling from current system
Developer Experience
- Auto-discovery of identity provider endpoints
- Clear error messages for configuration issues
- Simple development setup with device flow
- Comprehensive examples and documentation
- Testing utilities for OAuth 2.1 scenarios
Migration Strategy
Phase 1: Parallel Support
- Keep existing API key system functional
- Add OAuth 2.1 as optional authentication method
- Allow hybrid configuration (API keys + OAuth 2.1)
Phase 2: Migration Tooling
// Migration helper
pub struct AuthMigrationTool {
current_config: ApiKeyConfig,
target_config: OAuth21Config,
}
impl AuthMigrationTool {
pub async fn migrate_to_oauth21(&self) -> Result<(), MigrationError> {
// Guided migration process
}
}Phase 3: Deprecation Path
- Mark API key system as deprecated
- Provide migration timeline (6 months)
- Maintain backward compatibility during transition
References & Research
Official MCP Standards
- MCP Security Best Practices 2025
- AWS MCP OAuth 2.1 Implementation Guide
- Auth0 MCP Authorization Guide
Technical Specifications
Industry Implementation Examples
Success Metrics
- Compliance: 100% OAuth 2.1 specification compliance
- Security: Passes automated security scanning
- Performance: <5ms authentication overhead
- Adoption: 90% of new deployments use OAuth 2.1
- Enterprise: Integration with 3+ identity providers
This brings the framework into full compliance with 2025 MCP security standards and enables enterprise adoption with proper identity management integration.
Priority: High - Required for standards compliance and enterprise adoption
Effort: High - Comprehensive OAuth 2.1 implementation
Impact: High - Enables enterprise deployments and future-proofs security
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request