Skip to content

fix(auth): support standard OpenAI Authorization and x-api-key headers in remote mode - #496

Closed
yangs1202 wants to merge 3 commits into
lidge-jun:devfrom
yangs1202:codex/support-standard-auth-header-remote-mode
Closed

fix(auth): support standard OpenAI Authorization and x-api-key headers in remote mode#496
yangs1202 wants to merge 3 commits into
lidge-jun:devfrom
yangs1202:codex/support-standard-auth-header-remote-mode

Conversation

@yangs1202

@yangs1202 yangs1202 commented Jul 26, 2026

Copy link
Copy Markdown

Summary

When opencodex is bound to a non-loopback address (remote mode where isApiAuthRequired is true), the requireResponsesApiAuth helper previously only accepted the custom x-opencodex-api-key header.

Standard OpenAI SDKs and third-party client integrations (such as Cursor, LangChain, or direct HTTP clients) authenticate using the standard Authorization: Bearer <API_KEY> or x-api-key headers. As a result, standard OpenAI-compatible client requests to /v1/responses, /v1/chat/completions, and /v1/responses/compact were rejected with a 401 authentication_error ("opencodex API key required").

Change: Updated requireResponsesApiAuth to use hasValidApiAuth(req, config), which supports the standard Authorization: Bearer <token> header, x-api-key, and x-opencodex-api-key.

Verification

  • bun run typecheck — clean
  • bun run test — all tests pass
  • Added tests in tests/server-auth.test.ts verifying that requireResponsesApiAuth accepts standard Authorization: Bearer <token>, x-api-key, and x-opencodex-api-key on non-loopback bindings.

Checklist

  • Target branch is dev.
  • Scope stays focused and avoids unrelated cleanup.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • Bug Fixes

    • Improved authentication for the Responses API.
    • Standard Authorization: Bearer and x-api-key credentials are now accepted alongside supported OpenCode API keys.
    • Invalid or mismatched credentials are consistently rejected with an unauthorized response.
  • Release

    • Updated the application version to 2.7.40.

lidge-jun and others added 3 commits July 25, 2026 23:15
.codexclaw/ is listed in .gitignore (line 11) but these two files were
committed before the ignore rule took effect, so they stayed tracked on
main as well. Local goalplan state is agent scratch data and does not
belong in the repository.

Files remain on disk; only the index entries are removed.
@github-actions github-actions Bot added the bug Something isn't working label Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d241e602-575a-4367-86c7-5d9f80ffef26

📥 Commits

Reviewing files that changed from the base of the PR and between b448570 and ca14005.

📒 Files selected for processing (6)
  • .codexclaw/goalplans/opencodex-codex-260725-bug-sweep-gui-enhancement/goalplan.json
  • .codexclaw/goalplans/opencodex-codex-260725-bug-sweep-gui-enhancement/ledger.jsonl
  • package.json
  • src/server/auth-cors.ts
  • src/server/index.ts
  • tests/server-auth.test.ts
💤 Files with no reviewable changes (2)
  • .codexclaw/goalplans/opencodex-codex-260725-bug-sweep-gui-enhancement/goalplan.json
  • .codexclaw/goalplans/opencodex-codex-260725-bug-sweep-gui-enhancement/ledger.jsonl

📝 Walkthrough

Walkthrough

Changes

Responses API authentication

Layer / File(s) Summary
Shared Responses credential validation
src/server/auth-cors.ts (lines 180-186), src/server/index.ts (line 116), tests/server-auth.test.ts (lines 25, 282-313)
requireResponsesApiAuth now uses shared API validation for bearer, x-api-key, and x-opencodex-api-key credentials; the guard is re-exported and covered by authentication tests.

Release metadata

Layer / File(s) Summary
Package version update
package.json (line 3)
The package version changes from 2.7.35 to 2.7.40.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ResponsesRequest
  participant requireResponsesApiAuth
  participant hasValidApiAuth
  participant ProxyAdmissionSecrets
  ResponsesRequest->>requireResponsesApiAuth: submit request credentials
  requireResponsesApiAuth->>hasValidApiAuth: validate supported auth headers
  hasValidApiAuth->>ProxyAdmissionSecrets: compare configured secrets
  ProxyAdmissionSecrets-->>hasValidApiAuth: validation result
  hasValidApiAuth-->>requireResponsesApiAuth: valid or invalid
  requireResponsesApiAuth-->>ResponsesRequest: admit request or return 401
Loading

Suggested reviewers: ingwannu, lidge-jun, wibias

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: remote auth now accepts standard OpenAI Authorization and x-api-key headers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@yangs1202 yangs1202 closed this Jul 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca14005c3e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/server/auth-cors.ts
if (!isApiAuthRequired(config)) return null;
const actual = req.headers.get("x-opencodex-api-key")?.trim();
if (actual && isProxyAdmissionSecret(actual, config)) return null;
if (hasValidApiAuth(req, config)) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Check every supported admission header before rejecting

When a remote direct-mode client sends its upstream Codex credential in Authorization and the proxy credential in the newly supported x-api-key, hasValidApiAuth selects the nonempty Authorization value first and compares only that value, so the valid x-api-key is ignored and this gate returns 401. The same problem occurs whenever an invalid higher-priority header accompanies a valid lower-priority one; accept the request when any supported admission header matches rather than selecting the first nonempty header.

AGENTS.md reference: AGENTS.md:L65-L71

Useful? React with 👍 / 👎.

Comment thread package.json
{
"name": "@bitkyc08/opencodex",
"version": "2.7.35",
"version": "2.7.40",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Leave the version bump to the release script

Once this feature commit is promoted to main, attempting to release 2.7.40 through scripts/release.ts reaches npm version 2.7.40 --no-git-tag-version with the package already at that version and exits with Version not changed before the release commit or workflow dispatch. Local npm version --help confirms that accepting the same version requires the opt-in --allow-same-version, which the release script does not pass. Revert this unrelated bump and let the release authority create the dedicated version commit after its preflight checks.

AGENTS.md reference: AGENTS.md:L19-L22

Useful? React with 👍 / 👎.

Comment thread src/server/auth-cors.ts
* Codex Direct. Remote binds must use the dedicated proxy header so the two bearer
* domains can never be confused.
* Admission for OpenAI Responses transports.
* Supports OpenAI standard Authorization header (Bearer <token>), x-api-key, and x-opencodex-api-key.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document the newly supported remote authentication headers

This adds user-facing support for x-api-key, but the remote-access sections in README.md and docs-site/src/content/docs/reference/configuration.md still direct clients to x-opencodex-api-key and do not mention this new alternative; several translated configuration pages likewise state that clients must use the dedicated header. Update the English source and translations so users of standard integrations can discover the behavior and the locales no longer contradict it.

AGENTS.md reference: AGENTS.md:L78-L79

Useful? React with 👍 / 👎.

Comment thread src/server/auth-cors.ts
if (!isApiAuthRequired(config)) return null;
const actual = req.headers.get("x-opencodex-api-key")?.trim();
if (actual && isProxyAdmissionSecret(actual, config)) return null;
if (hasValidApiAuth(req, config)) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the proxy bearer out of Cursor authentication

When a non-loopback request selects a Cursor provider without provider.apiKey and authenticates through the newly accepted Authorization: Bearer <proxy-secret>, this gate admits the request, headersForCodexAuthContext preserves that header, and resolveCursorToken uses it as the Cursor access token before the transport sends it upstream. This exposes OPENCODEX_API_AUTH_TOKEN or a dashboard-generated admission key to the Cursor endpoint and still fails authentication there; strip recognized admission credentials before adapter forwarding or retain a separate admission header for routes that consume caller bearers.

AGENTS.md reference: AGENTS.md:L65-L71

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants