Skip to content

Fix Anthropic-compatible auth headers - #24

Merged
OnlyTerp merged 2 commits into
sybil-solutions:mainfrom
eafire15:codex/fix-anthropic-auth-headers
Jun 1, 2026
Merged

Fix Anthropic-compatible auth headers#24
OnlyTerp merged 2 commits into
sybil-solutions:mainfrom
eafire15:codex/fix-anthropic-auth-headers

Conversation

@eafire15

@eafire15 eafire15 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Some Anthropic-compatible providers expect authentication via x-api-key and reject requests when an additional Authorization: Bearer ... header is present.

This updates Anthropic route headers to send only x-api-key by default. Custom headers can still be supplied through extra_headers.

Testing

  • /Users/chrisd/codex-shim/.venv/bin/python -m pytest tests/test_server.py::test_chat_routes_to_anthropic

@eafire15
eafire15 marked this pull request as ready for review June 1, 2026 21:12
@eafire15

eafire15 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

@0xSero this is like my 3rd github PR ever. And I did the very best vibing to codex xhigh i could to deliver you this. ultimately, its what worked for me and I'm vibing my way with multiple models in codex app. Maybe it doesnt merge and I'm sorry. but thank you for doing what you do 0x!

@0xSero

0xSero commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

@0xSero this is like my 3rd github PR ever. And I did the very best vibing to codex xhigh i could to deliver you this. ultimately, its what worked for me and I'm vibing my way with multiple models in codex app. Maybe it doesnt merge and I'm sorry. but thank you for doing what you do 0x!

@OnlyTerp please review if u can

I appreciate your contribution.

@OnlyTerp

OnlyTerp commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

@0xSero this is like my 3rd github PR ever. And I did the very best vibing to codex xhigh i could to deliver you this. ultimately, its what worked for me and I'm vibing my way with multiple models in codex app. Maybe it doesnt merge and I'm sorry. but thank you for doing what you do 0x!

@OnlyTerp please review if u can

I appreciate your contribution.

On it. Love this community I'll have this handled very shortly

@OnlyTerp
OnlyTerp merged commit 14a05ba into sybil-solutions:main Jun 1, 2026
2 checks passed
@OnlyTerp

OnlyTerp commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Merged! 🎉 Thank you @eafire15 — this is a genuinely correct fix.

The real Anthropic Messages API authenticates with x-api-key, and Authorization: Bearer <key> was redundant for it. More importantly, several Anthropic-compatible gateways reject requests that carry both headers, so your change makes the shim work against stricter upstreams. It also already matches the auth flow documented in the README routing diagram (x-api-key: apiKey, anthropic-version: …), so the code now matches the docs.

Nothing is lost for the providers that do want a bearer token — since extra_headers are spread before the setdefault calls, anyone who needs it can still supply Authorization via extraHeaders.

What I did before merging:

  • Verified the change against all Anthropic auth paths (/messages and the compact path both flow through _anthropic_headers).
  • Ran the full suite — green on Python 3.11 and 3.12 (your new assert "Authorization" not in captured["headers"] guards the regression nicely).
  • Bundled a CHANGELOG.md entry into the merge so it's documented for the next release.

For a 3rd-ever PR this is clean, well-tested, and well-reasoned. Exactly the kind of contribution we love to see — please keep them coming. 🙏

@eafire15

eafire15 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

"Merged! 🎉 Thank you @eafire15 — this is a genuinely correct fix." Whaaaaaaat?! it WORKED??? LETS GOOOOO! Does this make me a.... software engineer?!?! Thank you @OnlyTerp for getting through it, I'll do my best to try and contribute where i can to a great piece by @0xSero !

Samuel86-star added a commit to Samuel86-star/codex-shim that referenced this pull request Jun 6, 2026
Bring in 5 upstream commits:
- feat: Auto Router for per-task model selection (855e459)
- test: Auto Router integration suite (17c4125)
- feat: Cursor Composer subscription passthrough (27b6e5e)
- feat: Windows quota launcher (f6a89f9)
- fix: Anthropic auth uses x-api-key only (sybil-solutions#24) (14a05ba)

Conflict resolutions
====================

codex_shim/cli.py — kept BOTH sides where they were complementary:
  * Conflict sybil-solutions#1 (picker needle): kept our regex-based MODEL_PICKER_NEEDLE
    (it handles both the old model-queries-*.js inlined form AND the new
    models-and-reasoning-efforts-*.js extracted form), AND kept upstream's
    new SYSTEM_CODEX_APP / USER_CODEX_APP Path constants (referenced by
    upstream's patched_codex_app_bundle() and resign helpers).
    Rationale: upstream's literal needle does not match recent Codex
    Desktop bundles; ours does. Upstream's Path constants are required by
    other upstream code we're adopting.
  * Conflict sybil-solutions#2 (exec_codex_app): layered fallback rather than a stitch.
    Order: patched bundle (upstream) -> codex CLI (upstream's original) ->
    macOS `open -a Codex` (our no-CLI fix) -> error. Each layer is
    independently meaningful; nothing is mashed together.

codex_shim/server.py — accepted upstream entirely.
  The four conflicts (chat_completions routing, responses_compact ChatGPT
  branch, the _route method body and signature, _route return type) were
  all expressions of the same substitution: vision_router was replaced by
  the more general Auto Router (which subsumes vision routing via
  candidate.supports_images hard-zeroing on image tasks). Upstream's
  ShimServer rewrites _route from `(body) -> tuple[ShimModel, body]`
  back to `(body) -> ShimModel` and moves image-aware decisions into
  router.pick_candidate, so we keep nothing from our old signature.
  Independent of the substitution, we re-applied the diagnostic
  `[route] slug=... provider=... upstream_model=... url=` print in
  _post_openai_chat and _post_anthropic — those are operational logging,
  not vision-routing logic, and would otherwise be silently dropped.

Deletions accepted as part of the substitution
==============================================
  codex_shim/vision_router.py, tests/test_vision_router.py,
  VISION_ROUTING.md, VISION_ROUTING_CN.md,
  IMPLEMENTATION_SUMMARY.md, IMPLEMENTATION_SUMMARY_CN.md.
The Auto Router covers the image-routing use case via supports_images
candidate metadata; strip_images_from_history is intentionally not
ported because Auto Router decides per task and does not switch models
mid-conversation.

Verification
============
`pytest tests/ --ignore=tests/test_hostguard.py` → 120 passed, 1 failed.
The one failure (test_join_url_handles_versioned_bases) reproduces on
plain upstream/main and is unrelated to this merge; flagged for a
separate fix.
jomangbp pushed a commit to jomangbp/codex-shim that referenced this pull request Jul 6, 2026
Anthropic route headers now send only x-api-key (plus anthropic-version)
and no longer also attach Authorization: Bearer <apiKey>. Some
Anthropic-compatible gateways reject requests that carry both headers.
Providers that genuinely require a bearer token can still supply one via
extraHeaders.

Co-authored-by: OnlyTerp <121772140+OnlyTerp@users.noreply.github.com>
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.

3 participants