OAuth MCP proxy
OAuth 2.1 authentication library for Go MCP servers.
Supports both MCP SDKs:
✅
mark3labs/mcp-go✅
modelcontextprotocol/go-sdk(official)
One-time setup: Configure provider + add WithOAuth() to your server. Result: All tools automatically protected with token validation and caching.
mark3labs/mcp-go
import "github.com/tuannvm/oauth-mcp-proxy/mark3labs"
oauthServer, oauthOption, _ := mark3labs.WithOAuth(mux, &oauth.Config{
Provider: "okta",
Issuer: "https://your-company.okta.com",
Audience: "api://your-mcp-server",
})
mcpServer := server.NewMCPServer("Server", "1.0.0", oauthOption)
streamable := server.NewStreamableHTTPServer(mcpServer, /*options*/)
mux.HandleFunc("/mcp", oauthServer.WrapMCPEndpoint(streamable))Official SDK
Why Use This Library?
Dual SDK support - Works with both mark3labs and official SDKs
Simple integration - One
WithOAuth()call protects all toolsAutomatic 401 handling - RFC 6750 compliant error responses with OAuth discovery
Zero per-tool config - All tools automatically protected
Fast token caching - 5-min cache with JWT expiry awareness
Security hardened - State replay protection, DoS prevention, input validation
Built-in rate limiting - Token-based rate limiter included
CORS support - OPTIONS pass-through for browser clients
Multiple providers - HMAC, Okta, Google, Azure AD
How It Works
Request Flow
Token Validation Flow
What oauth-mcp-proxy does:
Extracts Bearer tokens from HTTP requests
Validates against your OAuth provider (with caching)
Adds authenticated user to request context
All your tools automatically protected
🔒 Security Features
Production-ready security hardening built-in:
State Replay Protection
Timestamp + nonce validation - States include timestamp and nonce for replay attack prevention
Automatic nonce cleanup - Expired nonces removed before replay check (prevents memory leaks)
Rolling deploy compatible - Accepts legacy states without timestamp/nonce for zero-downtime upgrades
Token Security
JWT expiry-aware caching - Cache respects token expiration time (uses min(token.expiry, now+5min))
Constant-time HMAC comparison - Timing attack prevention for signature verification
Secure nonce generation - Panics on crypto/rand failure (no weak fallback)
Input Validation & DoS Prevention
Parameter length limits - code, state, code_challenge validated to prevent abuse
Request body size limits - MaxBytesReader on token endpoint (1MB), registration (256KB)
Issuer URL validation - Enforced HTTPS for non-localhost OIDC providers
Session Management (Official SDK)
auth.TokenInfo population - Populates go-sdk auth context for session binding
User-based session tracking - Prevents session hijacking via user ID verification
HTTP Security
Security headers - CSP, X-Frame-Options, X-Content-Type-Options, Cache-Control
CORS support - OPTIONS pass-through for browser clients
RFC 6750 compliant - Proper WWW-Authenticate headers with resource_metadata
Built-in Rate Limiting
Breaking Changes (Security Hardening)
v1.0.0 → v1.1.0
The following security improvements introduce breaking changes:
1. Issuer URL Validation (CRITICAL)
Change: OIDC providers now enforce HTTPS validation for issuer URLs
Impact: Invalid issuer URLs will cause
NewServer()to failMigration: Ensure your
Issuerconfig uses HTTPS (or localhost for testing)
2. State Signing Key Initialization
Change:
NewServer()now panics if state signing key cannot be generatedImpact: Server startup will fail if crypto/rand fails (should never happen on healthy systems)
Migration: Ensure your system has a working CSPRNG. No code changes needed.
3. Nonce Generation Failure Behavior
Change:
generateSecureNonce()now panics instead of falling back to weak timestamp-based noncesImpact: OAuth authorization requests will fail if crypto/rand fails
Migration: Ensure your system has a working CSPRNG. No code changes needed.
4. Error Message Simplification
Change: Security-sensitive error messages are less verbose to prevent information leakage
Impact: Debugging authentication failures may require checking logs
Migration: Use server logs for detailed debugging; client errors are intentionally generic
No Migration Needed For
Token cache expiry fix - Fully backwards compatible
State replay protection - Legacy states without timestamp/nonce still accepted
Input validation - Only affects malformed requests
go-sdk adapter fixes - Fully backwards compatible
Quick Start
Using mark3labs/mcp-go
1. Install
2. Add to Your Server
3. Access Authenticated User
Using Official SDK
1. Install
2. Add to Your Server
Your MCP server now requires OAuth authentication.
Examples
See examples/README.md for detailed setup guide including Okta configuration.
Supported Providers
Documentation
Getting Started:
Setup Guide - Complete server integration and client configuration
Configuration Guide - All config options
Provider Setup - OAuth provider guides
Advanced:
Security Guide - Production best practices
Troubleshooting - Common issues
License
MIT License - See LICENSE
Last updated
Was this helpful?