Skip to content

openai-codex OAuth login does not honor proxy env for oauth/token exchange and refresh #42176

@leozhengliu-pixel

Description

@leozhengliu-pixel

Summary

openclaw models auth login --provider openai-codex can fail behind a proxy even when the same machine can successfully use both the official Codex CLI and Codex app through that proxy.

The failure happens during the final OAuth token exchange / refresh step. The browser authorization page works, the localhost callback works, but the https://auth.openai.com/oauth/token request does not consistently honor proxy environment variables.

Environment

  • OpenClaw: 2026.3.8
  • macOS: Apple Silicon
  • Proxy setup:
    • HTTP_PROXY=http://127.0.0.1:9098
    • HTTPS_PROXY=http://127.0.0.1:9098
    • ALL_PROXY=socks5://127.0.0.1:9099
    • NO_PROXY=localhost,127.0.0.1,::1

Symptoms

Running:

openclaw models auth login --provider openai-codex

would open the browser auth page successfully, but fail after redirect/callback with:

[openai-codex] code->token failed: 403 {"error":{"code":"unsupported_country_region_territory",...}}
Error: Token exchange failed

On the same machine, with the same proxy setup:

  • official codex CLI login works
  • Codex desktop/app login works

So this is not a general connectivity issue on the host.

Root Cause

OpenClaw delegates this flow to:

@mariozechner/pi-ai/dist/utils/oauth/openai-codex.js

In that file, both of these functions used bare fetch(TOKEN_URL, ...):

  • exchangeAuthorizationCode()
  • refreshAccessToken()

They did not explicitly use undici's EnvHttpProxyAgent or equivalent proxy-aware dispatcher.

That means:

  • browser authorization can go through the user's browser/system proxy
  • localhost callback works
  • but the OAuth token exchange / refresh request path in OpenClaw itself may not reliably go through the configured proxy

Minimal Fix

Patch the OAuth helper to explicitly honor proxy env by wiring EnvHttpProxyAgent into the token exchange and refresh fetch calls.

Example local fix that resolved the issue:

let _EnvHttpProxyAgent = null;

if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
  import("undici").then((m) => {
    _EnvHttpProxyAgent = m.EnvHttpProxyAgent;
  }).catch(() => {
    _EnvHttpProxyAgent = null;
  });
}

function getProxyAwareFetchOptions() {
  const proxy =
    process.env.HTTPS_PROXY ||
    process.env.HTTP_PROXY ||
    process.env.ALL_PROXY ||
    process.env.https_proxy ||
    process.env.http_proxy ||
    process.env.all_proxy;

  if (!proxy?.trim() || !_EnvHttpProxyAgent) return {};

  try {
    return { dispatcher: new _EnvHttpProxyAgent() };
  } catch {
    return {};
  }
}

Then use it in both token requests:

const response = await fetch(TOKEN_URL, {
  ...getProxyAwareFetchOptions(),
  method: "POST",
  ...
});

Verification

After applying the patch locally, the same login flow completed successfully:

OpenAI OAuth complete
Auth profile: openai-codex:default (openai-codex/oauth)

Why this looks like a bug

OpenClaw already has proxy-aware handling in other network paths, but this specific openai-codex OAuth token exchange / refresh path is inconsistent with that behavior.

Expected behavior:

  • if proxy env is configured, openai-codex OAuth token exchange and refresh should honor it the same way other OpenClaw network requests do

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions