Repository navigation
fix(auth): accept valid x-api-key even when an Authorization header is present (Claude Code) - #2926
Closed
omar-nahhas wants to merge 1 commit into
Closed
omar-nahhas wants to merge 1 commit into
omar-nahhas wants to merge 1 commit into
Conversation
…nts)
Claude Code with an active claude.ai session (or ANTHROPIC_AUTH_TOKEN set)
sends an Authorization bearer ALONGSIDE the x-api-key. Both the edge guard
and the SSE handlers picked the Authorization header first and never fell
back, so a valid provisioned key 401'd whenever any bearer was present —
api.anthropic.com authenticates on x-api-key regardless.
- guard + auth service now validate all presented credentials in order
- new resolveClientApiKey() returns the credential that actually validated,
so per-key usage attribution records the real key, not a stale bearer
- all /v1 handlers (chat, embeddings, search, fetch, stt, tts, image, video)
and the Gemini-native route switched to the multi-credential check
- 401s on /v1/messages now use the standard Anthropic error envelope
({type:"error",error:{type:"authentication_error",...}}) so anthropic
SDKs/Claude Code surface the message instead of an opaque body
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
golamrabbi696
added a commit
to golamrabbi696/EzRouter
that referenced
this pull request
Aug 12, 2026
6 of 7 tasks
Contributor
Author
|
Superseded by #5091 (rebased onto current master). |
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.
Problem
Anthropic clients can send an
Authorization: Bearer …header alongsidex-api-key. Claude Code does this whenever the user has an active claude.ai session orANTHROPIC_AUTH_TOKENset whileANTHROPIC_API_KEYpoints at 9router. The real Anthropic API authenticates onx-api-keyregardless of other headers — but 9router'sextractApiKey(both indashboardGuard.jsandsrc/sse/services/auth.js) picks the Authorization bearer first and never falls back, so a valid client API key gets 401 whenever any bearer is present.Reproduction against a 9router instance with
requireApiKeyenabled:Fix
Authorizationbearer,x-api-key,x-goog-api-key,?key=) in precedence order and accept the request if any of them validates.resolveClientApiKey()returns the credential that actually validated, so per-key usage attribution records the real key instead of a stale bearer./v1handlers (chat/messages, embeddings, search, fetch, stt, tts, image, video) and the Gemini-native/v1betaroute use the multi-credential check./v1/messagesnow return the standard Anthropic error envelope ({"type":"error","error":{"type":"authentication_error",…}}) so Claude Code and anthropic SDKs surface the message instead of an opaque body. Other endpoints keep their existing error shape.Tests
tests/unit/dashboard-guard.test.js).unit/dashboard-guard,unit/embeddingsCore,unit/image-generation,unit/gemini-native-endpoint,unit/gemini-tts,unit/xai-video-handler,unit/minimax-tts,unit/kiro-nonstream-error: 112/112 passing on this branch.🤖 Generated with Claude Code