Skip to content

fix: cache rejected credentials for 60s instead of re-validating each request - #51

Merged
fatwang2 merged 1 commit into
mainfrom
claude/project-thread-40h31l
Oct 24, 2026
Merged

fatwang2 merged 1 commit into
mainfrom
claude/project-thread-40h31l

Conversation

@fatwang2

Copy link
Copy Markdown
Member

Requested by fatwang2 · project thread

Why

Every MCP request validates its Bearer credential by calling GET /usage on the API. A copilot-cli client holding a dead token has been pinging /mcp every 6 seconds since 2026-10-22 23:00 UTC, and it never re-authorizes. Each ping cost one /usage call, 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

  • New cacheRejectedCredentials(validator) in src/http.ts remembers rejected credentials (sha256 of the token) for 60 seconds. During that window the server answers with the same 401 invalid_token challenge without calling the API. This matches the gateway's own 60s cache of failed token validation.
  • Only rejections are cached. Accepted credentials are still validated on every exchange, and validation outages (thrown errors, 503) are not cached.
  • The cache holds at most 10,000 entries and evicts the oldest first.
  • createHttpApp wraps 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

… 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
@fatwang2 fatwang2 self-assigned this Oct 24, 2026
@fatwang2
fatwang2 merged commit d75f3a6 into main Oct 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants