Repository navigation
fix: solve #5513 — back off /api/auth/token mints on a broken session - #5515
Closed
github-actions[bot] wants to merge 1 commit into
Closed
github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
Add a circuit breaker + in-flight coalescing to JwtApiAuthProvider so a wedged session can't storm /api/auth/token.
|
Ready to review this PR? Stage has broken it down into 3 individual chapters for you:
Chapters generated by Stage for commit c814377 on Jul 8, 2026 8:33am UTC. |
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.
Root cause
JwtApiAuthProvider.getJwt()(host-service) mints a JWT by exchanging the session token at/api/auth/token. On failure it simply threw without caching anything, and there was no in-flight coalescing. Because the cloud tRPC client callsgetHeaders()→getJwt()on every request (andinvalidateCache()on 401), a broken session turned every request into a fresh network mint with no backoff. A wedged multi-workspace client can generate hundreds ofPOST /api/auth/tokencalls per session (the issue reports ~600, ~300× the healthy baseline).That storm is what tripped Vercel's per-IP rate mitigation (
x-vercel-mitigated: deny), which then 403'd the login endpoint behind the same blanket rule — a self-locking loop where the human couldn't re-authenticate to clear the broken state.This PR addresses item #1 from the issue (client-side backoff / circuit breaker). Items #2 (surfacing
x-vercel-mitigated: denyas a real UI error) and #3 (server-side firewall scoping of/api/auth/desktop/connect) are out of scope here.The fix
In
JwtApiAuthProvider:1s → 2s → 4s … capped at 5 min). While the cooldown is activegetJwt()rejects immediately with the last error instead of re-hitting/api/auth/token. A success resets the backoff.This collapses a broken-session burst from hundreds of requests to a slow trickle, well under any rate-based mitigation.
Tests
JwtAuthProvider.test.ts:getHeaders()calls now issue ≤3 network fetches (was 50, one per call).Closes #5513
Summary by cubic
Add a circuit breaker and in-flight coalescing to
JwtApiAuthProviderto stop repeated/api/auth/tokenmints when a session is broken. Addresses #5513 by backing off failed mints to avoid rate-mitigated lockouts.getJwt()fails fast with the last error; success resets.getJwt()calls so only one network mint runs on a cold cache.Written for commit c814377. Summary will update on new commits.