Enterprise managed authorization#770
Enterprise managed authorization#770radar07 wants to merge 10 commits intomodelcontextprotocol:mainfrom
Conversation
- Adds the Token Exchange (RFC 8693) for Enterprise-Managed Authorization
|
Hi @radar07, thanks for submitting this PR. Could you link the issue that it is addressing? Also, as a heads-up: it will likely take some time to review your proposal. Both because it's quite large, but more importantly I'm also working on a proposal how to structure the client-side OAuth implementation and this change will need to be aligned with it. |
|
Thanks @maciej-kisiel. I updated the description with the SEP that this PR solves. |
|
@maciej-kisiel I'd be happy to contribute to OAuth implementation. Let me know if I can help with anything. Just want to know if I should add conformance tests to this because I can see that there are PRs related to conformance tests. |
maciej-kisiel
left a comment
There was a problem hiding this comment.
I took a brief look at your PR and I believe we could utilize the oauth2 library more aggressively.
Please also take a look at my PR/proposal for client-side OAuth at #785. I think this PR could be expressed with the proposed abstractions, but your OAuth expertise would make the feedback valuable.
|
|
||
| // JWTBearerResponse represents the response from a JWT Bearer grant request | ||
| // per RFC 7523. This uses the standard OAuth 2.0 token response format. | ||
| type JWTBearerResponse struct { |
There was a problem hiding this comment.
Could https://pkg.go.dev/golang.org/x/oauth2#Token be used for this?
| } | ||
|
|
||
| // JWTBearerError represents an error response from a JWT Bearer grant request. | ||
| type JWTBearerError struct { |
There was a problem hiding this comment.
Could https://pkg.go.dev/golang.org/x/oauth2#RetrieveError be used for this?
| // "mcp-client-secret", | ||
| // nil, | ||
| // ) | ||
| func ExchangeJWTBearer( |
There was a problem hiding this comment.
It feels like https://pkg.go.dev/golang.org/x/oauth2#Config.Exchange could be used to replicate the behavior of the function. Is there any reason not to use it?
| mediaType, _, err := mime.ParseMediaType(ct) | ||
| if err != nil || mediaType != "application/json" { | ||
| return nil, fmt.Errorf("bad content type %q", ct) | ||
| ct := strings.TrimSpace(strings.SplitN(res.Header.Get("Content-Type"), ";", 2)[0]) |
There was a problem hiding this comment.
Could you comment why special behavior is needed in place of mime.ParseMediaType?
| // } | ||
| // | ||
| // resp, err := ExchangeToken(ctx, idpTokenEndpoint, req, clientID, clientSecret, nil) | ||
| func ExchangeToken( |
There was a problem hiding this comment.
It looks like https://pkg.go.dev/golang.org/x/oauth2#Config.Exchange can be used for Token Exchange as well? golang/oauth2#409
|
|
||
| // TokenExchangeResponse represents the response from a token exchange request | ||
| // per RFC 8693 Section 2.2. | ||
| type TokenExchangeResponse struct { |
There was a problem hiding this comment.
Same comments as in oauthex/jwt_bearer.go apply to the request and error types.
auth,oauthex: implement Enterprise Managed Authorization (SEP-990)This PR implements Enterprise Managed Authorization (SEP-990) for the Go MCP SDK, enabling MCP Clients and Servers to leverage enterprise Identity Providers for seamless authorization without requiring users to authenticate separately to each MCP Server.
Overview
Enterprise Managed Authorization follows the Identity Assertion Authorization Grant specification (draft-ietf-oauth-identity-assertion-authz-grant), implementing a three-step flow:
This enables:
Closes: #628