Problem
Gateway lanes (deepseek, minimax, and openrouter from #31) run the stock claude binary against a third-party endpoint. Before injecting the gateway's settings, childEnvironment in runner/run.ts removes every inherited ANTHROPIC_* variable plus the names in GATEWAY_INHERITED_CONFLICTS (runner/flex-providers.ts). Neither list contains CLAUDE_CODE_OAUTH_TOKEN.
If a parent shell exports CLAUDE_CODE_OAUTH_TOKEN (for example from claude setup-token), a gateway child inherits it. We have not verified which credential Claude Code sends when both ANTHROPIC_AUTH_TOKEN and CLAUDE_CODE_OAUTH_TOKEN are set. If the OAuth token wins or is sent alongside, a claude.ai subscription credential reaches a third-party endpoint. The runner's OAuth guard only checks .credentials.json in the lane's config dir, so it cannot catch a token that arrives through the environment.
Fix
- Add
CLAUDE_CODE_OAUTH_TOKEN to GATEWAY_INHERITED_CONFLICTS.
- Extend the
lists every alternative Claude provider selector test in flex-providers.test.ts and the env-dump test in run.test.ts to assert it never reaches a gateway child.
- Check whether any other Claude Code credential variable can be inherited the same way, and strip those too.
Done when
Found while planning OpenRouter support (#7, plan in docs/plans/2026-10-05-openrouter-gateway.md). It affects the existing DeepSeek and MiniMax lanes, so it is a separate change with its own gate.
Problem
Gateway lanes (
deepseek,minimax, andopenrouterfrom #31) run the stockclaudebinary against a third-party endpoint. Before injecting the gateway's settings,childEnvironmentinrunner/run.tsremoves every inheritedANTHROPIC_*variable plus the names inGATEWAY_INHERITED_CONFLICTS(runner/flex-providers.ts). Neither list containsCLAUDE_CODE_OAUTH_TOKEN.If a parent shell exports
CLAUDE_CODE_OAUTH_TOKEN(for example fromclaude setup-token), a gateway child inherits it. We have not verified which credential Claude Code sends when bothANTHROPIC_AUTH_TOKENandCLAUDE_CODE_OAUTH_TOKENare set. If the OAuth token wins or is sent alongside, a claude.ai subscription credential reaches a third-party endpoint. The runner's OAuth guard only checks.credentials.jsonin the lane's config dir, so it cannot catch a token that arrives through the environment.Fix
CLAUDE_CODE_OAUTH_TOKENtoGATEWAY_INHERITED_CONFLICTS.lists every alternative Claude provider selectortest inflex-providers.test.tsand the env-dump test inrun.test.tsto assert it never reaches a gateway child.Done when
CLAUDE_CODE_OAUTH_TOKEN.bash scripts/check.shpasses.CLAUDE_CODE_OAUTH_TOKENexported in the parent shell, with evidence in the PR.Found while planning OpenRouter support (#7, plan in
docs/plans/2026-10-05-openrouter-gateway.md). It affects the existing DeepSeek and MiniMax lanes, so it is a separate change with its own gate.