Repository navigation
Preserve shared OAuth clients when a replica cannot read them - #922
Open
rudycelekli wants to merge 2 commits into
Open
rudycelekli wants to merge 2 commits into
rudycelekli wants to merge 2 commits into
Conversation
Treat missing or revoked credentials as absent, but propagate read/decryption faults before a dynamic registration can replace the client's shared credential. Keep malformed JSON recovery separate so parsing never leaks a stored secret. AI assistance: implemented and validated with OpenAI Codex; maintainer review remains required.
Implemented and validated with OpenAI Codex assistance.
rudycelekli
requested review from
MikeRyanDev,
davidmckayv,
dustywusty,
guidovizoso,
mxmzb,
samjulien and
tylerslaton
as code owners
October 31, 2026 05:30
This branch has not been deployed
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.
What this changes
A replica that cannot decrypt a stored dynamic OAuth client currently treats it as absent, registers a replacement, and points the shared server row at a client encrypted with its own key. A correctly configured replica then loses access to the client it was using.
Keep read/decryption faults distinct from an absent or revoked credential in both the initial lookup and the lookup under the registration lock. Failed reads now stop the connection attempt before a vendor registration or shared credential change. Connect records the authenticated person and app in a durable
mcp.oauth_client_read_failedevent, then returns a safe retryable 503. Only typed client-read faults take this path; vendor registration and later writes retain their existing handling. Malformed stored JSON still uses the existing recovery path, with its parsing error contained so plaintext cannot be relayed.Related: #786, item 3.
Where it runs
Boundary and audit
mcp.oauth_client_read_failedaudit row naming the authenticated actor and server, with fixed operation/reason fields and no thrown error or cause. It performs no registration or vault write.Changelog
Proof
Base:
743649efc3f21d7bf0badbe6af2bcd5daedd97ce. Candidate head:0dae797a9437fd5aae7eb649b6b377d57cd00248.d428f669f10e21700b6d5eb1fb14e90c9cc59cfe, on the same upstream base, ran the fulltest:ci: 11,017 passed, 210 skipped, two failed (recorder held-steps service-worker timing and concurrent routine-sweep queue expectation). Both cases passed when isolated on unchanged base and that routing candidate; suite-order/timing causality remains unresolved. That full run was not executed on this OAuth head, and is not claimed as a passing full-suite result here.The targeted tests use a dedicated disposable test database and injected vendor operations; no live vendor credentials or application database are used.
AI assistance: implemented and locally validated with OpenAI Codex. Maintainer approval and hosted CI remain required.