> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codezero.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Codex

> Set up cordon to give OpenAI Codex secure API access without exposing secrets.

Cordon integrates with [OpenAI Codex](https://github.com/openai/codex) so your AI agent can make authenticated API calls without holding real credentials.

<Warning>
  Current limitations: Cordon injects API keys for Codex, not ChatGPT/OAuth session credentials. Codex works best with Cordon in non-sandboxed sessions; `--dangerously-bypass-approvals-and-sandbox` is inherently riskier because model-generated commands run without Codex's normal sandbox boundary.
</Warning>

To run Codex outside its command sandbox, launch it with:

```bash theme={null}
codex --dangerously-bypass-approvals-and-sandbox
```

For non-interactive runs, use the same flag with `exec`:

```bash theme={null}
codex exec --dangerously-bypass-approvals-and-sandbox "your prompt here"
```

## Scope

Codex setup defaults to **project scope**: `cordon.toml` lives in `$CWD`, proxy env vars are written to `$CWD/.codex/.env`, and a Codex config block is written to `$CWD/.codex/config.toml`.

For **full startup-time coverage**, Codex must load the project-local `.env`, so point `CODEX_HOME` at the project directory at runtime:

```bash theme={null}
export CODEX_HOME="$PWD/.codex"
codex --dangerously-bypass-approvals-and-sandbox
```

Add this export to your shell profile or a project `.envrc` (e.g. direnv) to automate it.

To use a single cordon config across all projects, override to user scope:

```bash theme={null}
cordon setup codex --scope user
```

User scope writes env vars to `$CODEX_HOME/.env` (or `$HOME/.codex/.env` if `CODEX_HOME` is not set), writes shell command env policy to `$CODEX_HOME/config.toml`, and stores config at `$XDG_CONFIG_HOME/cordon/cordon.toml`. See [Scopes](/configuration/overview#scopes) for path details and trade-offs.

## Automated setup

The fastest way to get started:

```bash theme={null}
cordon setup codex
```

This:

1. Generates CA certificates (if not already present)
2. Creates a scaffold `cordon.toml`
3. Writes the standard proxy and CA env vars from [`cordon env`](/cli/env) to Codex's `.env` and `[shell_environment_policy.set]` in Codex's `config.toml`

Your existing `.env` is backed up to `.env.cordon.bak` before any changes are made.

To run cordon as a background service, run `cordon service install` after setup (add `--scope user` if you set up Codex with `--scope user`).

### Remove the setup

```bash theme={null}
cordon integration disable codex
```

## API key setup

Codex needs to be configured to use API key authentication (rather than OAuth) so traffic routes through cordon. Run `codex login`, select the API key option (option 3), and enter a dummy value:

```bash theme={null}
codex login
# Select: API key
# Enter: dummy-replaced-by-cordon
```

Cordon strips this dummy key and injects the real one from your secret store at the network layer.

## Adding routes

<Note>
  The `cordon route`, `cordon start`, and `cordon service` commands below default to **project scope**. If you set up Codex with `--scope user`, append `--scope user` to each of these commands so they target `~/.config/cordon/cordon.toml` instead of `./cordon.toml`.
</Note>

After setup, add a route for OpenAI:

```bash theme={null}
cordon route add --name openai --host api.openai.com \
  --auth-type header --header-name Authorization --scheme Bearer --source keyring --account openai
```

If you chose keyring as the secret source, store the secret:

```bash theme={null}
cordon secret set openai
```

See [Routes](/configuration/routes#provider-auth-quick-reference) for provider auth types, dummy-key behavior, and route change restart guidance.

## Manual setup

Prefer `cordon setup codex` for Codex configuration. It writes the proxy and CA settings to the right files, updates the shell environment policy, and backs up existing files before changing them. If setup cannot cover your environment, copy the values from [`cordon env`](/cli/env) to the appropriate Codex `.env` file.

```bash theme={null}
HTTPS_PROXY="http://127.0.0.1:<PORT>"
SSL_CERT_FILE="/path/to/combined-ca.pem"
```

<Note>
  Codex filters out `CODEX_*` prefixed variables from its `.env` file as a security measure, so you must use `SSL_CERT_FILE` instead of `CODEX_CA_CERTIFICATE`. If you need to set `CODEX_CA_CERTIFICATE`, it must be in your shell environment (e.g., `~/.zshrc`), not in the `.env` file.
</Note>

The `CODEX_HOME` env var can override the default `~/.codex/` path if Codex is installed in a non-standard location.

For shell commands and tools launched by Codex, set the same values in `config.toml`:

```toml theme={null}
[shell_environment_policy.set]
HTTPS_PROXY = "http://127.0.0.1:<PORT>"
SSL_CERT_FILE = "/path/to/combined-ca.pem"
```

Project-local `.codex/config.toml` can help trusted projects without setting `CODEX_HOME`, but `.codex/.env` is still the full startup-time path for Codex's own network traffic. See [Any tool (generic)](/guides/generic) for the full env-var contract.

## How it works

Codex is a Rust CLI that uses `reqwest` for HTTP and `rustls` for TLS. It loads `$CODEX_HOME/.env` via `dotenvy` at startup (before any threads are created), so proxy env vars are picked up automatically. It also applies `shell_environment_policy.set` from `config.toml` to shell commands and tools it launches later.

For Cordon's matched-route TLS behavior and certificate troubleshooting, see [TLS](/configuration/tls).

### WebSocket fallback

Codex prefers WebSocket connections (`wss://`) for the OpenAI realtime API. WebSocket connections through cordon's MITM currently fail with a TLS handshake error — Codex gracefully detects this and falls back to HTTP/SSE for the remainder of the session. The credential injection works identically on both transports; only the connection upgrade fails. WebSocket support is tracked in a future release.

## Workflow

Once configured, the workflow is:

1. Start cordon: `cordon start` (or use the background service)
2. Start Codex as usual
3. When Codex makes API calls to `api.openai.com`, cordon transparently injects credentials
4. Codex never sees or logs real API keys

<Tip>
  Use `cordon doctor` to diagnose any setup issues. It checks config validity, cert paths, trust store status, and port availability.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Codex still uses OAuth instead of API key">
    If Codex is connecting to `chatgpt.com` or `ab.chatgpt.com` instead of `api.openai.com`, it's using the OAuth path. Run `codex login`, select option 3 (API key), and enter a dummy value. Check cordon's logs — you should see `MITM: injecting credentials route=openai` for `api.openai.com` requests.
  </Accordion>

  <Accordion title="Certificate errors">
    Verify the active Codex `.env` includes the CA bundle values from [`cordon env`](/cli/env), then follow [TLS troubleshooting](/configuration/tls#troubleshooting-certificate-errors).
  </Accordion>

  <Accordion title="Proxy not being used">
    Verify the env vars are in the active Codex `.env`:

    ```bash theme={null}
    cat "$CODEX_HOME/.env"
    ```

    If the file exists but Codex isn't routing through the proxy, use the shared [proxy not running checks](/guides/process-management#proxy-not-running-checks).
  </Accordion>

  <Accordion title="CODEX_CA_CERTIFICATE not working from .env">
    Codex silently filters out all `CODEX_*` prefixed variables from its `.env` file. Use `SSL_CERT_FILE` instead, or set `CODEX_CA_CERTIFICATE` in your shell profile (`~/.zshrc` or `~/.bashrc`).
  </Accordion>

  <Accordion title="New routes not taking effect">
    Restart Cordon after adding or editing route definitions. See [Routes: route changes and secret rotation](/configuration/routes#route-changes-and-secret-rotation).
  </Accordion>

  <Accordion title="401 Unauthorized errors">
    1. Verify the secret is stored: `cordon secret set openai`
    2. Check the route auth config — OpenAI uses `type: header`, `header_name: Authorization`, and `scheme: Bearer`
    3. HTTP route secrets are fetched per-request — if you changed a secret, the next request picks it up automatically
  </Accordion>
</AccordionGroup>
