Repository navigation
fix: cache rejected credentials for 60s instead of re-validating each request - #51
Merged
Merged
Conversation
… request A client holding a dead token (a copilot-cli instance pinging every 6s) made the MCP server call GET /usage on every attempt, and each call was recorded as a 401 on the API. About a third of the API's errors on 2026-10-23 came from this one client. Rejected credentials are now refused locally for 60s, matching the gateway's cache of failed token validation. Accepted credentials and validation outages are not cached. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fa3q1VE4eQehywgL3KnHfu
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.
Requested by fatwang2 · project thread
Why
Every MCP request validates its Bearer credential by calling
GET /usageon the API. A copilot-cli client holding a dead token has been pinging/mcpevery 6 seconds since 2026-10-22 23:00 UTC, and it never re-authorizes. Each ping cost one/usagecall, and the gateway recorded each one as a 401. On 2026-10-23 (Beijing time) that was 10,687 of the API's 31,402 error requests, and it is still going.What
cacheRejectedCredentials(validator)insrc/http.tsremembers rejected credentials (sha256 of the token) for 60 seconds. During that window the server answers with the same401 invalid_tokenchallenge without calling the API. This matches the gateway's own 60s cache of failed token validation.createHttpAppwraps whichever validator it uses with the cache.Effect: a client like this one drops from about 600 to 1,200 API calls an hour to about 60. A user who re-authorizes gets a new token, so they are not affected. A key that is re-enabled is accepted again within 60 seconds.
Testing
npm test: 49/49 pass, including two new tests (cache expiry and eviction, accepted credentials and outages not cached, and repeated MCP requests with a dead token validating only once).Generated by Claude Code