Repository navigation
fix(core): replay completed MCP OAuth refreshes - #60896
Closed
Antonio-Faure wants to merge 1 commit into
Closed
Antonio-Faure wants to merge 1 commit into
Antonio-Faure wants to merge 1 commit into
Conversation
Rotating refresh tokens reject a second use. The in-flight map only shared requests until the response arrived, so a second location could read the old token before saveTokens persisted the rotated one and send it again.\n\nKeep successful refresh responses for 60s keyed by the consumed token and replay them to late callers. Failed refreshes remain retryable.
Contributor
|
Thanks for tracking this down and adding a regression test for it! I think this duplicates #53275, which is still open:
If your test covers something #53275 doesn't (for example the staggered caller from #60612), you could share it there, or review or test that pull request. |
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.
Issue for this PR
Fixes #60612
Type of change
What does this PR do?
A remote MCP server with rotating refresh tokens can receive two refreshes for the same token. The in-flight map in
packages/core/src/mcp/oauth.tsonly shares a request until its response arrives. A second location can read the old refresh token beforesaveTokenshas persisted the rotated one, send it again, getinvalid_grant, and delete the shared credential.Successful refresh responses are now kept for 60 seconds, keyed by the same URL/client/refresh-token tuple, and replayed to late callers. Failed refreshes are not cached, so a real failure remains retryable.
This covers the in-process race described in #60612. Serializing refreshes across separate OpenCode processes would be a separate follow-up using the credential file lock.
How did you verify your code works?
From
packages/core:bun test test/mcp-oauth.test.ts— 23 passed. The new test fails onbf544cdand passes with the change.bun typecheck— no errors (1,859 files).The new test runs two sequential
refreshAuthorizationcalls with the same old token against a server that only accepts that token once, and asserts one network request and the same rotated response.Checklist