Codex ChatGPT auth should inject host access token via egress #109

Closed
opened 2026-05-29 03:03:02 -04:00 by didericis-codex · 2 comments
Collaborator

Problem

Codex bottles using ChatGPT/device login can reach chatgpt.com after adding the host to egress, but requests to chatgpt.com/backend-api/codex/... still return 403. The egress proxy strips agent-originated Authorization headers and only re-injects auth for routes that declare an egress-owned token. A bare chatgpt.com route therefore forwards Codex requests without the ChatGPT bearer token.

Proposed fix

Use host-authorized Codex auth as the source of truth, but keep the token out of the agent container:

  1. Require the operator to run codex login --device-auth on the host.
  2. At bottle launch/provision time, read ~/.codex/auth.json on the host and extract only tokens.access_token.
  3. Add/render chatgpt.com as an authenticated egress route, e.g. auth_scheme: Bearer with an EGRESS_TOKEN_N slot.
  4. Pass the extracted access token only into the sidecar/egress environment, not the agent environment or env files.
  5. Let egress strip any agent Authorization header and inject the host-derived bearer for chatgpt.com.

This mirrors the Claude egress-owned auth shape while avoiding copying ~/.codex/auth.json or refresh credentials into the agent.

Caveats / follow-up

  • tokens.access_token expires, so the minimal version may require restarting the bottle after host Codex refreshes auth.
  • A stronger follow-up is a Codex-specific egress auth provider that can refresh sidecar-held credentials or re-read a host-owned refreshed access token without exposing refresh material to the agent.
  • Hot-apply is not enough for this today: adding auth to a running bare chatgpt.com route preserves existing route auth, and new EGRESS_TOKEN_N slots do not automatically receive env values in the running sidecar.

Acceptance criteria

  • A Codex bottle with host ChatGPT auth can call chatgpt.com/backend-api/codex/... through egress without forwarding any agent-held auth token.
  • The agent container does not receive OPENAI_API_KEY, CODEX_ACCESS_TOKEN, tokens.access_token, tokens.refresh_token, or auth.json.
  • Egress/pipelock route output remains non-secret: route files contain only host/path/auth slot metadata, never token values.
  • Expired/missing host Codex auth fails with a clear operator-facing message.
## Problem Codex bottles using ChatGPT/device login can reach `chatgpt.com` after adding the host to egress, but requests to `chatgpt.com/backend-api/codex/...` still return 403. The egress proxy strips agent-originated `Authorization` headers and only re-injects auth for routes that declare an egress-owned token. A bare `chatgpt.com` route therefore forwards Codex requests without the ChatGPT bearer token. ## Proposed fix Use host-authorized Codex auth as the source of truth, but keep the token out of the agent container: 1. Require the operator to run `codex login --device-auth` on the host. 2. At bottle launch/provision time, read `~/.codex/auth.json` on the host and extract only `tokens.access_token`. 3. Add/render `chatgpt.com` as an authenticated egress route, e.g. `auth_scheme: Bearer` with an `EGRESS_TOKEN_N` slot. 4. Pass the extracted access token only into the sidecar/egress environment, not the agent environment or env files. 5. Let egress strip any agent `Authorization` header and inject the host-derived bearer for `chatgpt.com`. This mirrors the Claude egress-owned auth shape while avoiding copying `~/.codex/auth.json` or refresh credentials into the agent. ## Caveats / follow-up - `tokens.access_token` expires, so the minimal version may require restarting the bottle after host Codex refreshes auth. - A stronger follow-up is a Codex-specific egress auth provider that can refresh sidecar-held credentials or re-read a host-owned refreshed access token without exposing refresh material to the agent. - Hot-apply is not enough for this today: adding auth to a running bare `chatgpt.com` route preserves existing route auth, and new `EGRESS_TOKEN_N` slots do not automatically receive env values in the running sidecar. ## Acceptance criteria - A Codex bottle with host ChatGPT auth can call `chatgpt.com/backend-api/codex/...` through egress without forwarding any agent-held auth token. - The agent container does not receive `OPENAI_API_KEY`, `CODEX_ACCESS_TOKEN`, `tokens.access_token`, `tokens.refresh_token`, or `auth.json`. - Egress/pipelock route output remains non-secret: route files contain only host/path/auth slot metadata, never token values. - Expired/missing host Codex auth fails with a clear operator-facing message.
didericis added the Kind/Enhancement label 2026-05-29 03:04:29 -04:00
Owner

Should require an explicit "forward_host_credentials" flag in the agent_provider manifest for this to happen, but otherwise looks good

Should require an explicit "forward_host_credentials" flag in the agent_provider manifest for this to happen, but otherwise looks good
Author
Collaborator

Agreed. I would make agent_provider.forward_host_credentials an explicit opt-in gate for this path. Default stays false, so a Codex bottle can still use device login interactively, but bot-bottle will not read ~/.codex/auth.json or forward any host-derived token unless the bottle declares that intent.

That gives the implementation a clean policy shape:

  • agent_provider.template: codex alone does not forward host auth material.
  • agent_provider.forward_host_credentials: true permits the launcher to read host Codex auth, validate it is ChatGPT auth with a fresh access token, and place only the access token in the egress sidecar env.
  • The agent container still never receives auth.json, refresh tokens, or access-token env vars.
  • Missing/expired host auth should fail launch with an operator-facing message that says to run codex login --device-auth on the host.

I would add that flag to the issue acceptance criteria before implementing.

Agreed. I would make `agent_provider.forward_host_credentials` an explicit opt-in gate for this path. Default stays false, so a Codex bottle can still use device login interactively, but bot-bottle will not read `~/.codex/auth.json` or forward any host-derived token unless the bottle declares that intent. That gives the implementation a clean policy shape: - `agent_provider.template: codex` alone does not forward host auth material. - `agent_provider.forward_host_credentials: true` permits the launcher to read host Codex auth, validate it is ChatGPT auth with a fresh access token, and place only the access token in the egress sidecar env. - The agent container still never receives `auth.json`, refresh tokens, or access-token env vars. - Missing/expired host auth should fail launch with an operator-facing message that says to run `codex login --device-auth` on the host. I would add that flag to the issue acceptance criteria before implementing.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: didericis/bot-bottle#109