Repository navigation
auth: support OAuth2 session persistence - #1058
Merged
guglielmo-san merged 6 commits intoJul 13, 2026
Merged
Conversation
jba
requested changes
Jul 8, 2026
jba
requested changes
Jul 8, 2026
smlx
force-pushed
the
oauth2-session-save
branch
from
July 10, 2026 03:34
7615caf to
13c5f7b
Compare
This change adds NewTokenSource and InitialTokenSource fields to AuthorizationCodeHandlerConfig. NewTokenSource enables wrapping the underlying token source to intercept token refreshes. InitialTokenSource enables configuring the token source used by the AuthorizationCodeHandler on initialization. Together these features facilitate persisting OAuth2 sessions across restarts. Includes a package example demonstrating the persistence pattern.
Add a mutex to AuthorizationCodeHandler to prevent data races when reading or updating the tokenSource and grantedScopes fields.
smlx
force-pushed
the
oauth2-session-save
branch
from
July 10, 2026 03:44
13c5f7b to
5c4846d
Compare
jba
reviewed
Jul 10, 2026
jba
left a comment
Contributor
There was a problem hiding this comment.
I approve, but an official maintainer needs to make the final call.
guglielmo-san
approved these changes
Jul 10, 2026
jba
approved these changes
Jul 13, 2026
This was referenced Oct 21, 2026
Closed
guglielmo-san
added a commit
to luiacuaniello/go-sdk
that referenced
this pull request
Oct 21, 2026
…handlers (modelcontextprotocol#1432) Fixes modelcontextprotocol#1430. Fixes modelcontextprotocol#1431. Two fixes to how the `extauth` handlers manage their token source. They change the same lines of `ClientCredentialsHandler.Authorize`, so they come in one PR, one commit each. **Token source bound to the `Authorize` context (modelcontextprotocol#1430)** `ClientCredentialsHandler.Authorize` built its token source with `clientcredentials.Config.TokenSource(ctx)`, where `ctx` is the context passed to `Authorize`. `clientcredentials` keeps that context and uses it for every later token request. The transport calls `Authorize` from a request- or connect-scoped context and keeps using the token source for the whole connection, so once that context was done and the first access token expired, every request failed with `context canceled`. `setMCPHeaders` only re-authorizes after an `invalid_grant` `RetrieveError`, so the connection did not recover. modelcontextprotocol#988 fixed the same problem in `AuthorizationCodeHandler`. The first token is now requested with `ctx`, so that `Authorize` still honors its context, and the token source used afterwards is built on a background context that carries the configured HTTP client. The fake authorization server now applies `Config.AccessTokenTTL` to the client_credentials grant too, so tests can make its token expire. **Unsynchronized token source (modelcontextprotocol#1431)** `ClientCredentialsHandler` and `EnterpriseHandler` wrote their `tokenSource` (and, for `ClientCredentialsHandler`, `grantedScopes`) in `Authorize` and read it in `TokenSource` without synchronization. The streamable client transport calls `Authorize` for any request that fails with 401 or 403, and `TokenSource` before every request, so concurrent requests race on that state. `AuthorizationCodeHandler` guards the same fields with a mutex since modelcontextprotocol#1058. Both handlers now guard them with a `sync.RWMutex`. **Tests** - `TestClientCredentialsHandler_TokenAfterContextCancel`: after the context passed to `Authorize` is cancelled, the token source still gets a new token once the first one has expired. Fails without the first commit. - `TestClientCredentialsHandler_ConcurrentAuthorize` and `TestEnterpriseHandler_ConcurrentAuthorize`: run `Authorize` and `TokenSource` from several goroutines. Fail under the race detector without the second commit. `go test ./...`, `go test -race` on `auth` and `mcp`, `go vet ./...`, staticcheck v0.6.1 and the client conformance suite (0.2.0-alpha.11, run as in CI with the baseline) pass. --------- Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change adds NewTokenSource and InitialTokenSource fields to AuthorizationCodeHandlerConfig. NewTokenSource enables wrapping the underlying token source to intercept token refreshes. InitialTokenSource enables configuring the token source used by the
AuthorizationCodeHandler on initialization. Together these features facilitate persisting OAuth2 sessions across restarts.
Includes a package example demonstrating the persistence pattern.
Fixes: #901.
See #901 for the previous discussion behind this design.