Commit 6ccc07c
authored
feat: auto-detect RFC 8707 resource parameter for OAuth flows (smart-mcp-proxy#188)
* Create spec
* docs: add RFC 8707 resource auto-detection specification and plan
Related smart-mcp-proxy#165
Add comprehensive specification and implementation plan for automatic
detection of the RFC 8707 resource parameter in OAuth flows. This enables
zero-config OAuth for providers like Runlayer that require the resource
parameter.
Artifacts:
- spec.md: Feature specification with user stories and requirements
- plan.md: Implementation plan with technical context
- research.md: Technical research and implementation approach
- data-model.md: Entity definitions and state transitions
- quickstart.md: Usage guide and troubleshooting
- checklists/requirements.md: Specification quality checklist
Key Decisions:
- Extract resource from RFC 9728 Protected Resource Metadata
- Fallback to server URL if metadata unavailable
- Inject params into auth URL after mcp-go constructs it
- Manual extra_params override auto-detected values
* docs: add implementation tasks for RFC 8707 resource auto-detection
Related smart-mcp-proxy#165
Add structured task list with 39 tasks organized by user story:
- Phase 1: Setup (1 task)
- Phase 2: Foundational - discovery layer (5 tasks)
- Phase 3: US1 - Zero-config auto-detection (15 tasks) - MVP
- Phase 4: US2 - Manual override (6 tasks)
- Phase 5: US3 - Token injection (4 tasks)
- Phase 6: US4 - Diagnostic visibility (3 tasks)
- Phase 7: Polish (5 tasks)
Tasks follow TDD approach per constitution requirements.
* feat: add DiscoverProtectedResourceMetadata for RFC 8707 resource detection
Related smart-mcp-proxy#165
Add new function that returns the full RFC 9728 Protected Resource Metadata
struct including the 'resource' field needed for RFC 8707 compliance.
Refactor DiscoverScopesFromProtectedResource to delegate to new function.
Changes:
- Add DiscoverProtectedResourceMetadata() returning *ProtectedResourceMetadata
- Refactor DiscoverScopesFromProtectedResource() as wrapper for backward compat
- Add comprehensive unit tests for new function
Testing:
- All TestDiscoverProtectedResourceMetadata_* tests pass
- Existing DiscoverScopesFromProtectedResource tests still pass
* feat(oauth): implement RFC 8707 resource auto-detection (User Story 1)
Add automatic detection of RFC 8707 resource parameter from Protected
Resource Metadata (RFC 9728). This enables zero-config OAuth with
providers like Runlayer that require the resource parameter.
Key changes:
- Add CreateOAuthConfigWithExtraParams() that returns both OAuth config
and auto-detected extra params including resource
- Add autoDetectResource() helper that:
- Makes preflight HEAD request to get WWW-Authenticate header
- Extracts resource_metadata URL
- Fetches Protected Resource Metadata
- Uses metadata.resource or falls back to server URL
- Update handleOAuthAuthorization() to accept extraParams and inject
them into authorization URL
- Update all 6 call sites to use new function and pass extraParams
Tests:
- TestCreateOAuthConfig_AutoDetectsResource: verifies resource extraction
- TestCreateOAuthConfig_FallsBackToServerURL: verifies fallback behavior
- E2E tests in e2e_oauth_zero_config_test.go
Part of smart-mcp-proxy#165 (RFC 8707 resource auto-detection for zero-config OAuth)
* feat(oauth): add tests for manual extra_params override (US2)
Tests verify that:
- T022: Manual extra_params.resource overrides auto-detected value
- T023: Manual extra_params are preserved while resource is auto-detected
Implementation was already complete from US1:
- T024-T026: Merge logic and logging in CreateOAuthConfigWithExtraParams
All tests pass: go test ./internal/oauth/... -v -run TestCreateOAuthConfig
* feat(oauth): pass auto-detected extraParams to transport wrapper (US3)
Enable auto-detected resource parameter injection into token requests:
- T029: OAuthTransportWrapper.injectFormParams() handles token exchange/refresh
- T030: createOAuthConfigInternal() accepts extraParams for wrapper injection
- T031: Existing TestInjectFormParams_TokenRequest covers token request injection
Key changes:
- CreateOAuthConfig() now delegates to createOAuthConfigInternal()
- CreateOAuthConfigWithExtraParams() passes auto-detected params to internal fn
- Transport wrapper uses passed extraParams instead of re-reading from config
This ensures zero-config OAuth flows inject resource into all OAuth requests:
- Authorization URL (via handleOAuthAuthorization)
- Token exchange (via transport wrapper)
- Token refresh (via transport wrapper)
* feat(oauth): add RFC 8707 resource visibility to diagnostics (US4)
* fix(oauth): use POST for resource auto-detection per MCP spec
MCP spec only requires POST support for the main endpoint. Use POST
directly for the preflight request to get WWW-Authenticate header
with resource_metadata URL.
Updated all tests to use POST method in mock handlers.
* fix(oauth): address code review feedback - add timeout, clarify comments, clean tests
* docs: add zero-config vs explicit OAuth examples, improve auth status output1 parent f0ca376 commit 6ccc07c
18 files changed
Lines changed: 2116 additions & 55 deletions
File tree
- cmd/mcpproxy
- docs/code-reviews
- internal
- management
- oauth
- server
- upstream/core
- specs/011-resource-auto-detect
- checklists
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
565 | 565 | | |
566 | 566 | | |
567 | 567 | | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
568 | 607 | | |
569 | 608 | | |
570 | | - | |
| 609 | + | |
571 | 610 | | |
572 | 611 | | |
573 | | - | |
| 612 | + | |
574 | 613 | | |
575 | 614 | | |
576 | 615 | | |
| |||
988 | 1027 | | |
989 | 1028 | | |
990 | 1029 | | |
| 1030 | + | |
| 1031 | + | |
991 | 1032 | | |
992 | 1033 | | |
993 | 1034 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
559 | 559 | | |
560 | 560 | | |
561 | 561 | | |
562 | | - | |
| 562 | + | |
563 | 563 | | |
564 | 564 | | |
| 565 | + | |
| 566 | + | |
565 | 567 | | |
566 | 568 | | |
567 | 569 | | |
| |||
570 | 572 | | |
571 | 573 | | |
572 | 574 | | |
573 | | - | |
| 575 | + | |
574 | 576 | | |
575 | 577 | | |
576 | 578 | | |
577 | 579 | | |
578 | 580 | | |
579 | | - | |
| 581 | + | |
580 | 582 | | |
581 | | - | |
| 583 | + | |
582 | 584 | | |
583 | | - | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
584 | 591 | | |
585 | 592 | | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
586 | 597 | | |
587 | 598 | | |
588 | 599 | | |
589 | | - | |
590 | | - | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
591 | 623 | | |
592 | | - | |
593 | | - | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
594 | 631 | | |
595 | 632 | | |
596 | 633 | | |
597 | 634 | | |
598 | 635 | | |
599 | 636 | | |
600 | 637 | | |
601 | | - | |
| 638 | + | |
602 | 639 | | |
603 | | - | |
| 640 | + | |
604 | 641 | | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
605 | 657 | | |
606 | 658 | | |
607 | 659 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
322 | 322 | | |
323 | 323 | | |
324 | 324 | | |
| 325 | + | |
| 326 | + | |
325 | 327 | | |
326 | | - | |
327 | 328 | | |
328 | | - | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
329 | 334 | | |
330 | | - | |
331 | 335 | | |
332 | | - | |
333 | 336 | | |
334 | | - | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
335 | 342 | | |
336 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
337 | 360 | | |
338 | 361 | | |
339 | 362 | | |
340 | 363 | | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
341 | 371 | | |
342 | 372 | | |
343 | 373 | | |
| |||
Lines changed: 133 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
214 | | - | |
215 | | - | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
216 | 217 | | |
217 | 218 | | |
218 | 219 | | |
| |||
0 commit comments