feat(mcp): scope gateway session bearers to the RFC 8707 resource - #35045
Conversation
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
Greptile SummaryAdds RFC 8707 resource scoping to gateway MCP sessions
Confidence Score: 5/5The PR appears safe to merge No blocking failure remains
|
| Filename | Overview |
|---|---|
| litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py | Propagates validated per-server resource scope through the POST-bound authorization flow and rejects conflicting token exchanges |
| litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py | Transfers the sealed session resource scope onto the admitted user context for downstream authorization |
| litellm/proxy/_experimental/mcp_server/mcp_server_manager.py | Intersects live server grants with the admitted session scope across normal and fallback entitlement paths |
| litellm/proxy/_experimental/mcp_server/outbound_credentials/session_token.py | Adds an optional resource server identifier to session token claims while retaining the unscoped wire shape |
| litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py | Accepts and forwards RFC 8707 resource parameters through aggregate authorization and token endpoints |
| litellm/proxy/_experimental/mcp_server/oauth_utils.py | Exposes canonical resource URI normalization for shared resource resolution |
| litellm/proxy/_types.py | Adds a server-only excluded field carrying the admitted session resource restriction |
| tests/test_litellm/proxy/_experimental/mcp_server/test_gateway_dcr_flow.py | Covers scoped authorization, conflicting redemption, refresh propagation, and unscoped compatibility |
| tests/test_litellm/proxy/_experimental/mcp_server/auth/test_user_api_key_auth_mcp.py | Covers admission-time propagation of scoped and unscoped session claims |
| tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py | Covers scope intersection across entitlement unions and resolver-failure fallback behavior |
Reviews (4): Last reviewed commit: "feat(mcp): scope gateway session bearers..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
eb27d65 to
7ab8a10
Compare
7ab8a10 to
7723635
Compare
|
bugbot run |
7723635 to
aff3ef9
Compare
|
bugbot run |
aff3ef9 to
fcb1a5e
Compare
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fcb1a5e. Configure here.
|
QA'd live on a real proxy: scoped bearer is refused on out-of-scope |
TLDR
Problem this solves:
resourceparam spec clients send was ignoredHow it solves it:
resourceseals that server through flow, code, and session tokensUser Flow
Before: a user connects an MCP client to one gateway server, and the token the client walks away with silently works on every server that user can reach
client_idresource) and receives a bearer tokenAfter: the same connection walk hands the client a token that works only on the server it asked for
client_idresource) and receives a bearer tokenresourcethan it was issued for fails withinvalid_targetRelevant issues
resourceparameter at/authorizeand/token; a value resolving to exactly one gateway-managed oauth2 server scopes the session to it, and the token endpoint rejects a conflicting redemption withinvalid_targeton both grantsLinear ticket
Part of LIT-4917
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
Live proxy on
localhost:4917at commit fcb1a5e, real Postgres, real public upstream (mcp.deepwiki.com). Servers:wiki_oauth(gateway-managed oauth2,allow_all_keys, a vaulted per-user token seeded viaPOST /v1/mcp/server/{id}/oauth-user-credential) anddeepwiki(auth none,allow_all_keys), so an unscoped session reaches both and the only narrowing in play is the sealed scopeType
🆕 New Feature
Caveats (if any)
Final Attestation
Note
Cursor Bugbot is generating a summary for commit fcb1a5e. Configure here.