Skip to content

Commit 9456e0e

Browse files
committed
feat: Add OAuth 2.1 support with PKCE, RFC 9728, RFC 8707 compliance
1 parent 27c255b commit 9456e0e

19 files changed

+3258
-32
lines changed

.gitignore

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
README
2-
.env
3-
.vscode
4-
.idea
1+
node_modules/
2+
dist/
3+
*.log
54
.DS_Store
6-
dist
7-
node_modules
5+
*.env
6+
.env.local
7+
.env.*.local
8+
coverage/
9+
.nyc_output/
10+
*.tsbuildinfo
11+
.idea/
12+
.vscode/
13+
*.swp
14+
*.swo
15+
*~

CHANGES.md

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
# OAuth 2.1 Implementation - Change Log
2+
3+
## Summary
4+
5+
OAuth 2.1 authorization support has been added to the MCP Framework, implementing the Model Context Protocol authorization specification. This enables secure user authentication with authorization servers like AWS Cognito, Auth0, Okta, and others.
6+
7+
## New Files Created
8+
9+
### Core Implementation
10+
- **`src/auth/providers/oauth.ts`** (630+ lines)
11+
- Complete OAuth 2.1 provider with PKCE
12+
- Token validation (JWT and introspection)
13+
- Protected Resource Metadata generation
14+
- Authorization flow management
15+
- Token caching with configurable TTL
16+
17+
### Documentation
18+
- **`OAUTH_GUIDE.md`** - Comprehensive OAuth setup guide with:
19+
- Feature overview
20+
- Quick start examples
21+
- AWS Cognito setup instructions
22+
- Authorization flow details
23+
- Advanced configuration
24+
- Security considerations
25+
- Testing instructions
26+
- Troubleshooting guide
27+
28+
- **`OAUTH_IMPLEMENTATION_SUMMARY.md`** - Technical implementation summary
29+
- **`OAUTH_QUICK_START.md`** - 5-minute quick start guide
30+
31+
### Examples
32+
- **`examples/oauth-simple-example.ts`** - Minimal OAuth setup
33+
- **`examples/oauth-cognito-example.ts`** - Complete Cognito integration
34+
- **`examples/oauth-custom-validator.ts`** - Advanced token validation
35+
- **`examples/oauth-test-client.ts`** - OAuth testing client
36+
- **`examples/README.md`** - Examples documentation with flow diagrams
37+
38+
## Modified Files
39+
40+
### Core Framework
41+
42+
1. **`src/auth/types.ts`**
43+
- Added optional `headers` field to `AuthProvider.getAuthError()` return type
44+
- Added `oauth` endpoint option to `AuthConfig.endpoints`
45+
46+
2. **`src/auth/index.ts`**
47+
- Export `OAuthProvider` class
48+
- Export `OAuthConfig` type
49+
50+
3. **`src/transports/sse/types.ts`**
51+
- Added `oauth` configuration section with callback handlers
52+
- Updated `SSETransportConfigInternal` to include oauth option
53+
54+
4. **`src/transports/sse/server.ts`**
55+
- Added `/.well-known/oauth-protected-resource` endpoint (RFC 9728)
56+
- Added OAuth callback handler at `/oauth/callback`
57+
- Enhanced authentication handling with OAuth-specific WWW-Authenticate headers
58+
- Added `handleProtectedResourceMetadata()` method
59+
- Added `handleOAuthCallback()` method
60+
- Updated `handleAuthentication()` to support OAuth provider
61+
62+
5. **`README.md`**
63+
- Added OAuth 2.1 authentication section
64+
- Updated features list to mention OAuth support
65+
- Added links to OAuth documentation
66+
67+
## Features Implemented
68+
69+
### OAuth 2.1 Core
70+
- ✅ Authorization Code Flow with PKCE (RFC 7636)
71+
- ✅ Token validation (JWT and opaque tokens)
72+
- ✅ State parameter for CSRF protection
73+
- ✅ Token caching with configurable TTL
74+
- ✅ Automatic token cache cleanup
75+
76+
### RFC Compliance
77+
-**RFC 9728**: OAuth 2.0 Protected Resource Metadata
78+
- `/.well-known/oauth-protected-resource` endpoint
79+
- Automatic metadata generation
80+
81+
-**RFC 8707**: Resource Indicators for OAuth 2.0
82+
- `resource` parameter in authorization/token requests
83+
- Audience validation in tokens
84+
85+
-**RFC 8414**: OAuth 2.0 Authorization Server Metadata
86+
- Automatic metadata discovery
87+
- Endpoint caching
88+
89+
-**RFC 7636**: Proof Key for Code Exchange
90+
- SHA256 code challenge generation
91+
- Code verifier validation
92+
93+
### Security Features
94+
- ✅ Strict audience validation (prevents token misuse)
95+
- ✅ PKCE mandatory for all flows
96+
- ✅ WWW-Authenticate headers with proper metadata
97+
- ✅ Token passthrough prevention
98+
- ✅ Configurable security policies
99+
100+
### Integration Support
101+
- ✅ AWS Cognito compatibility
102+
- ✅ Auth0 support
103+
- ✅ Okta support
104+
- ✅ Custom token validators
105+
- ✅ Generic OAuth 2.1 server support
106+
107+
## API Changes
108+
109+
### New Exports from `mcp-framework`
110+
111+
```typescript
112+
// OAuth Provider
113+
export { OAuthProvider } from "./auth/providers/oauth.js";
114+
115+
// OAuth Types
116+
export type { OAuthConfig } from "./auth/providers/oauth.js";
117+
```
118+
119+
### New Configuration Options
120+
121+
```typescript
122+
// SSE Transport OAuth Configuration
123+
interface SSETransportConfig {
124+
oauth?: {
125+
onCallback?: (params: {
126+
accessToken: string;
127+
refreshToken?: string;
128+
expiresIn?: number;
129+
state?: string;
130+
}) => Promise<void> | void;
131+
132+
onError?: (error: Error, state?: string) => Promise<void> | void;
133+
};
134+
}
135+
136+
// OAuth Provider Configuration
137+
interface OAuthConfig {
138+
authorizationServer: string;
139+
clientId?: string;
140+
clientSecret?: string;
141+
resourceUri: string;
142+
callbackPath?: string;
143+
tokenEndpoint?: string;
144+
jwksUri?: string;
145+
requiredScopes?: string[];
146+
customValidator?: (token: string) => Promise<{ valid: boolean; data?: Record<string, any> }>;
147+
tokenCacheTTL?: number;
148+
supportDynamicRegistration?: boolean;
149+
authorizationEndpoint?: string;
150+
strictAudienceValidation?: boolean;
151+
metadata?: Record<string, any>;
152+
}
153+
```
154+
155+
## Usage Example
156+
157+
### Before (API Key)
158+
```typescript
159+
import { MCPServer, APIKeyAuthProvider } from "mcp-framework";
160+
161+
const server = new MCPServer({
162+
transport: {
163+
type: "sse",
164+
options: {
165+
auth: {
166+
provider: new APIKeyAuthProvider({
167+
keys: [process.env.API_KEY]
168+
})
169+
}
170+
}
171+
}
172+
});
173+
```
174+
175+
### After (OAuth with Cognito)
176+
```typescript
177+
import { MCPServer, OAuthProvider } from "mcp-framework";
178+
179+
const server = new MCPServer({
180+
transport: {
181+
type: "sse",
182+
options: {
183+
auth: {
184+
provider: new OAuthProvider({
185+
authorizationServer: "https://your-domain.auth.us-east-1.amazoncognito.com",
186+
clientId: process.env.COGNITO_CLIENT_ID,
187+
clientSecret: process.env.COGNITO_CLIENT_SECRET,
188+
resourceUri: "https://mcp.example.com",
189+
requiredScopes: ["openid", "profile"],
190+
}),
191+
endpoints: {
192+
sse: false,
193+
messages: true,
194+
}
195+
},
196+
oauth: {
197+
onCallback: async ({ accessToken, refreshToken }) => {
198+
console.log("User authorized successfully!");
199+
},
200+
onError: async (error) => {
201+
console.error("Authorization failed:", error);
202+
}
203+
}
204+
}
205+
}
206+
});
207+
```
208+
209+
## Backward Compatibility
210+
211+
**Fully Backward Compatible**
212+
213+
- All existing authentication providers (JWT, API Key) continue to work unchanged
214+
- OAuth is opt-in - no breaking changes to existing code
215+
- SSE transport works exactly as before if OAuth is not configured
216+
- No changes to STDIO transport
217+
218+
## Testing
219+
220+
### Automated Tests
221+
- OAuth provider can be unit tested independently
222+
- PKCE generation is deterministic and testable
223+
- Token validation logic is isolated
224+
225+
### Manual Testing
226+
- Test client provided (`examples/oauth-test-client.ts`)
227+
- Full example servers for various scenarios
228+
- Step-by-step testing instructions in documentation
229+
230+
## Documentation
231+
232+
| Document | Purpose |
233+
|----------|---------|
234+
| `OAUTH_GUIDE.md` | Complete setup and usage guide |
235+
| `OAUTH_QUICK_START.md` | 5-minute quick start |
236+
| `OAUTH_IMPLEMENTATION_SUMMARY.md` | Technical details |
237+
| `examples/README.md` | Example usage and flow diagrams |
238+
| `README.md` | Updated with OAuth section |
239+
240+
## Migration Guide
241+
242+
### From API Key to OAuth
243+
244+
1. Replace `APIKeyAuthProvider` with `OAuthProvider`
245+
2. Configure OAuth settings (authorization server, client ID, resource URI)
246+
3. Add OAuth callback handlers
247+
4. Update client to use OAuth flow instead of static API keys
248+
249+
### From JWT to OAuth
250+
251+
1. Replace `JWTAuthProvider` with `OAuthProvider`
252+
2. Configure authorization server (instead of JWT secret)
253+
3. Optionally use `customValidator` for JWT validation with JWKS
254+
4. Add OAuth callback handlers
255+
256+
## Known Limitations
257+
258+
1. **HTTP Only**: OAuth requires HTTP-based transport (SSE)
259+
2. **No Token Persistence**: Framework doesn't persist refresh tokens
260+
3. **Basic JWT Validation**: Use `customValidator` for production JWKS validation
261+
4. **No Dynamic Registration**: Clients must pre-register with auth server
262+
263+
## Future Enhancements
264+
265+
Planned improvements:
266+
- Built-in JWKS-based JWT validation
267+
- Refresh token management
268+
- Token revocation support
269+
- Full dynamic client registration (RFC 7591)
270+
- OpenID Connect support
271+
- Multi-tenant authorization
272+
273+
## Dependencies
274+
275+
No new dependencies added - uses existing dependencies:
276+
- `jsonwebtoken` (already present for JWT auth)
277+
- Native `crypto` module for PKCE
278+
- Native `fetch` for HTTP requests
279+
280+
## Performance
281+
282+
- Token validation results are cached (default 5 minutes)
283+
- PKCE session cleanup runs automatically
284+
- Authorization server metadata is cached (1 hour)
285+
- Minimal overhead - only validates tokens on protected endpoints
286+
287+
## Security Audit Checklist
288+
289+
✅ PKCE mandatory for all authorization flows
290+
✅ State parameter prevents CSRF
291+
✅ Strict audience validation prevents token misuse
292+
✅ Token caching reduces validation overhead
293+
✅ Tokens not logged or exposed
294+
✅ HTTPS enforcement for authorization server
295+
✅ Proper WWW-Authenticate headers
296+
✅ No token passthrough to upstream services
297+
298+
## Version
299+
300+
- **Implementation Date**: October 30, 2025
301+
- **MCP Framework Version**: 0.1.29+
302+
- **OAuth Specification**: OAuth 2.1 (draft-ietf-oauth-v2-1-13)
303+
304+
## Contributors
305+
306+
Implementation completed by AI Assistant for MCP Framework.
307+

0 commit comments

Comments
 (0)