core-agent-ide/codex-rs
Josh McKinney 4e68fb96e2
feat: add auth login diagnostics (#13797)
## Problem

Browser login failures historically leave support with an incomplete
picture. HARs can show that the browser completed OAuth and reached the
localhost callback, but they do not explain why the native client failed
on the final `/oauth/token` exchange. Direct `codex login` also relied
mostly on terminal stderr and the browser error page, so even when the
login crate emitted better sign-in diagnostics through TUI or app-server
flows, the one-shot CLI path still did not leave behind an easy artifact
to collect.

## Mental model

This implementation treats the browser page, the returned `io::Error`,
and the normal structured log as separate surfaces with different safety
requirements. The browser page and returned error preserve the detail
that operators need to diagnose failures. The structured log stays
narrower: it records reviewed lifecycle events, parsed safe fields, and
redacted transport errors without becoming a sink for secrets or
arbitrary backend bodies.

Direct `codex login` now adds a fourth support surface: a small
file-backed log at `codex-login.log` under the configured `log_dir`.
That artifact carries the same login-target events as the other
entrypoints without changing the existing stderr/browser UX.

## Non-goals

This does not add auth logging to normal runtime requests, and it does
not try to infer precise transport root causes from brittle string
matching. The scope remains the browser-login callback flow in the
`login` crate plus a direct-CLI wrapper that persists those events to
disk.

This also does not try to reuse the TUI logging stack wholesale. The TUI
path initializes feedback, OpenTelemetry, and other session-oriented
layers that are useful for an interactive app but unnecessary for a
one-shot login command.

## Tradeoffs

The implementation favors fidelity for caller-visible errors and
restraint for persistent logs. Parsed JSON token-endpoint errors are
logged safely by field. Non-JSON token-endpoint bodies remain available
to the returned error so CLI and browser surfaces still show backend
detail. Transport errors keep their real `reqwest` message, but attached
URLs are surgically redacted. Custom issuer URLs are sanitized before
logging.

On the CLI side, the code intentionally duplicates a narrow slice of the
TUI file-logging setup instead of sharing the full initializer. That
keeps `codex login` easy to reason about and avoids coupling it to
interactive-session layers that the command does not need.

## Architecture

The core auth behavior lives in `codex-rs/login/src/server.rs`. The
callback path now logs callback receipt, callback validation,
token-exchange start, token-exchange success, token-endpoint non-2xx
responses, and transport failures. App-server consumers still use this
same login-server path via `run_login_server(...)`, so the same
instrumentation benefits TUI, Electron, and VS Code extension flows.

The direct CLI path in `codex-rs/cli/src/login.rs` now installs a small
file-backed tracing layer for login commands only. That writes
`codex-login.log` under `log_dir` with login-specific targets such as
`codex_cli::login` and `codex_login::server`.

## Observability

The main signals come from the `login` crate target and are
intentionally scoped to sign-in. Structured logs include redacted issuer
URLs, redacted transport errors, HTTP status, and parsed token-endpoint
fields when available. The callback-layer log intentionally avoids
`%err` on token-endpoint failures so arbitrary backend bodies do not get
copied into the normal log file.

Direct `codex login` now leaves a durable artifact for both failure and
success cases. Example output from the new file-backed CLI path:

Failing callback:

```text
2026-03-06T22:08:54.143612Z  INFO codex_cli::login: starting browser login flow
2026-03-06T22:09:03.431699Z  INFO codex_login::server: received login callback path=/auth/callback has_code=false has_state=true has_error=true state_valid=true
2026-03-06T22:09:03.431745Z  WARN codex_login::server: oauth callback returned error error_code="access_denied" has_error_description=true
```

Succeeded callback and token exchange:

```text
2026-03-06T22:09:14.065559Z  INFO codex_cli::login: starting browser login flow
2026-03-06T22:09:36.431678Z  INFO codex_login::server: received login callback path=/auth/callback has_code=true has_state=true has_error=false state_valid=true
2026-03-06T22:09:36.436977Z  INFO codex_login::server: starting oauth token exchange issuer=https://auth.openai.com/ redirect_uri=http://localhost:1455/auth/callback
2026-03-06T22:09:36.685438Z  INFO codex_login::server: oauth token exchange succeeded status=200 OK
```

## Tests

- `cargo test -p codex-login`
- `cargo clippy -p codex-login --tests -- -D warnings`
- `cargo test -p codex-cli`
- `just bazel-lock-update`
- `just bazel-lock-check`
- manual direct `codex login` smoke tests for both a failing callback
and a successful browser login

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-06 15:00:37 -08:00
..
.cargo Fix release build take (#12865) 2026-02-25 20:59:07 -08:00
.config fix flaky test: approval_matrix_covers_all_modes (#7028) 2025-11-20 14:37:42 -08:00
.github/workflows chore(ci): add cargo audit workflow and policy (#7108) 2025-11-24 12:20:55 -08:00
ansi-escape feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
app-server feat: structured plugin parsing (#13711) 2026-03-06 11:08:36 -08:00
app-server-protocol feat: structured plugin parsing (#13711) 2026-03-06 11:08:36 -08:00
app-server-test-client feat(app-server-test-client): OTEL setup for tracing (#13493) 2026-03-04 13:30:09 -08:00
apply-patch fix: codex-arg0 no longer depends on codex-core (#12434) 2026-02-21 00:20:42 -08:00
arg0 feat: pass helper executable paths via Arg0DispatchPaths (#12719) 2026-02-24 17:44:38 -08:00
artifacts chore: ultra-clean artifacts (#13577) 2026-03-05 13:03:01 +00:00
async-utils feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
backend-client feat: support multiple rate limits (#11260) 2026-02-10 20:09:31 -08:00
chatgpt add @plugin mentions (#13510) 2026-03-06 00:03:39 +00:00
cli feat: add auth login diagnostics (#13797) 2026-03-06 15:00:37 -08:00
cloud-requirements config: enforce enterprise feature requirements (#13388) 2026-03-04 04:40:22 +00:00
cloud-tasks feat: split codex-common into smaller utils crates (#11422) 2026-02-11 12:59:24 +00:00
cloud-tasks-client add codex cloud list (#9324) 2026-01-16 08:56:38 -08:00
codex-api change sound (#13697) 2026-03-05 22:48:49 -08:00
codex-backend-openapi-models feat: support multiple rate limits (#11260) 2026-02-10 20:09:31 -08:00
codex-client Log headers in trace mode (#9214) 2026-01-14 18:38:12 +00:00
codex-experimental-api-macros feat: experimental flags (#10231) 2026-02-02 11:06:50 +00:00
config refactor: remove proxy admin endpoint (#13687) 2026-03-05 22:03:16 -08:00
core fix: move unit tests in codex-rs/core/src/codex.rs into their own file (#13783) 2026-03-06 11:56:49 -08:00
debug-client feat: add search term to thread list (#12578) 2026-02-25 09:59:41 +00:00
docs chore(app-server): delete v1 RPC methods and notifications (#13375) 2026-03-03 13:18:25 -08:00
exec [elicitations] Switch to use MCP style elicitation payload for mcp tool approvals. (#13621) 2026-03-06 01:50:26 -08:00
execpolicy execpolicy: add host_executable() path mappings (#12964) 2026-02-27 12:59:24 -08:00
execpolicy-legacy feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
feedback Add timestamps to feedback log lines (#13688) 2026-03-06 07:34:59 -07:00
file-search fix(core): scope file search gitignore to repository context (#13250) 2026-03-02 21:52:20 -07:00
hooks notify: include client in legacy hook payload (#12968) 2026-02-26 22:27:34 -08:00
keyring-store feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
linux-sandbox fix(linux-sandbox): always unshare bwrap userns (#13624) 2026-03-05 21:57:40 +00:00
lmstudio chore(deps): bump tracing from 0.1.43 to 0.1.44 in /codex-rs (#9880) 2026-01-26 15:48:45 -08:00
login feat: add auth login diagnostics (#13797) 2026-03-06 15:00:37 -08:00
mcp-server image-gen-event/client_processing (#13512) 2026-03-04 16:54:38 -08:00
network-proxy fix: reject global wildcard network proxy domains (#13789) 2026-03-06 21:06:24 +00:00
ollama chore: nuke chat/completions API (#10157) 2026-02-03 11:31:57 +00:00
otel chore(otel): reorganize codex-otel crate (#13800) 2026-03-06 14:58:18 -08:00
package-manager chore: ultra-clean artifacts (#13577) 2026-03-05 13:03:01 +00:00
process-hardening feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
protocol feat: structured plugin parsing (#13711) 2026-03-06 11:08:36 -08:00
responses-api-proxy Update pnpm versions to fix cve-2026-24842 (#12009) 2026-02-19 14:27:55 -08:00
rmcp-client [rmcp-client] Recover from streamable HTTP 404 sessions (#13514) 2026-03-06 10:02:42 -05:00
scripts Upgrade to rust 1.93 (#10080) 2026-01-28 17:46:18 +00:00
secrets Move sanitizer into codex-secrets (#12306) 2026-02-20 22:47:54 +00:00
shell-command Collapse parsed command summaries when any stage is unknown (#13043) 2026-03-03 19:45:34 +00:00
shell-escalation refactor: prepare unified exec for zsh-fork backend (#13392) 2026-03-05 08:55:12 +00:00
skills feat: skills for artifacts (#13525) 2026-03-05 12:02:02 +00:00
state fix bazel build (#13787) 2026-03-06 12:12:20 -08:00
stdio-to-uds feat: add support for building with Bazel (#8875) 2026-01-09 11:09:43 -08:00
test-macros feat: add large stack test macro (#12768) 2026-02-25 13:19:21 +00:00
tui feat: structured plugin parsing (#13711) 2026-03-06 11:08:36 -08:00
utils fix: pending messages in /agent (#13240) 2026-03-04 10:17:29 +00:00
vendor build(linux-sandbox): always compile vendored bubblewrap on Linux; remove CODEX_BWRAP_ENABLE_FFI (#11498) 2026-02-11 21:30:41 -08:00
windows-sandbox-rs copy current exe to CODEX_HOME/.sandbox-bin for apply_patch (#13669) 2026-03-05 22:15:10 -08:00
.gitignore [MCP] Prefix MCP tools names with mcp__ (#5309) 2025-10-19 20:41:55 -04:00
BUILD.bazel Add feature-gated freeform js_repl core runtime (#10674) 2026-02-11 12:05:02 -08:00
Cargo.lock feat: add auth login diagnostics (#13797) 2026-03-06 15:00:37 -08:00
Cargo.toml feat: bind package manager (#13571) 2026-03-05 11:57:13 +00:00
clippy.toml fix: switch rate limit reset handling to timestamps (#5304) 2025-10-17 17:39:37 -07:00
config.md Fix link to MCP Servers config section (#5301) 2025-10-17 14:58:27 -07:00
default.nix fix(nix): include libcap dependency on linux builds (#12415) 2026-02-20 19:32:15 -08:00
deny.toml feat: external artifacts builder (#13485) 2026-03-04 20:22:34 +00:00
node-version.txt Reduce js_repl Node version requirement to 22.22.0 (#12857) 2026-02-26 04:09:30 +00:00
README.md feat: memories in workspace write (#13467) 2026-03-04 13:00:26 +00:00
rust-toolchain.toml Revert "chore(deps): bump rust-toolchain from 1.93.0 to 1.93.1 in /co…dex-rs (#11886)" (#12035) 2026-02-17 12:29:03 -08:00
rustfmt.toml Update cargo to 2024 edition (#842) 2025-05-07 08:37:48 -07:00

Codex CLI (Rust Implementation)

We provide Codex CLI as a standalone, native executable to ensure a zero-dependency install.

Installing Codex

Today, the easiest way to install Codex is via npm:

npm i -g @openai/codex
codex

You can also install via Homebrew (brew install --cask codex) or download a platform-specific release directly from our GitHub Releases.

Documentation quickstart

What's new in the Rust CLI

The Rust implementation is now the maintained Codex CLI and serves as the default experience. It includes a number of features that the legacy TypeScript CLI never supported.

Config

Codex supports a rich set of configuration options. Note that the Rust CLI uses config.toml instead of config.json. See docs/config.md for details.

Model Context Protocol Support

MCP client

Codex CLI functions as an MCP client that allows the Codex CLI and IDE extension to connect to MCP servers on startup. See the configuration documentation for details.

MCP server (experimental)

Codex can be launched as an MCP server by running codex mcp-server. This allows other MCP clients to use Codex as a tool for another agent.

Use the @modelcontextprotocol/inspector to try it out:

npx @modelcontextprotocol/inspector codex mcp-server

Use codex mcp to add/list/get/remove MCP server launchers defined in config.toml, and codex mcp-server to run the MCP server directly.

Notifications

You can enable notifications by configuring a script that is run whenever the agent finishes a turn. The notify documentation includes a detailed example that explains how to get desktop notifications via terminal-notifier on macOS. When Codex detects that it is running under WSL 2 inside Windows Terminal (WT_SESSION is set), the TUI automatically falls back to native Windows toast notifications so approval prompts and completed turns surface even though Windows Terminal does not implement OSC 9.

codex exec to run Codex programmatically/non-interactively

To run Codex non-interactively, run codex exec PROMPT (you can also pass the prompt via stdin) and Codex will work on your task until it decides that it is done and exits. Output is printed to the terminal directly. You can set the RUST_LOG environment variable to see more about what's going on. Use codex exec --ephemeral ... to run without persisting session rollout files to disk.

Experimenting with the Codex Sandbox

To test to see what happens when a command is run under the sandbox provided by Codex, we provide the following subcommands in Codex CLI:

# macOS
codex sandbox macos [--full-auto] [--log-denials] [COMMAND]...

# Linux
codex sandbox linux [--full-auto] [COMMAND]...

# Windows
codex sandbox windows [--full-auto] [COMMAND]...

# Legacy aliases
codex debug seatbelt [--full-auto] [--log-denials] [COMMAND]...
codex debug landlock [--full-auto] [COMMAND]...

Selecting a sandbox policy via --sandbox

The Rust CLI exposes a dedicated --sandbox (-s) flag that lets you pick the sandbox policy without having to reach for the generic -c/--config option:

# Run Codex with the default, read-only sandbox
codex --sandbox read-only

# Allow the agent to write within the current workspace while still blocking network access
codex --sandbox workspace-write

# Danger! Disable sandboxing entirely (only do this if you are already running in a container or other isolated env)
codex --sandbox danger-full-access

The same setting can be persisted in ~/.codex/config.toml via the top-level sandbox_mode = "MODE" key, e.g. sandbox_mode = "workspace-write". In workspace-write, Codex also includes ~/.codex/memories in its writable roots so memory maintenance does not require an extra approval.

Code Organization

This folder is the root of a Cargo workspace. It contains quite a bit of experimental code, but here are the key crates:

  • core/ contains the business logic for Codex. Ultimately, we hope this to be a library crate that is generally useful for building other Rust/native applications that use Codex.
  • exec/ "headless" CLI for use in automation.
  • tui/ CLI that launches a fullscreen TUI built with Ratatui.
  • cli/ CLI multitool that provides the aforementioned CLIs via subcommands.

If you want to contribute or inspect behavior in detail, start by reading the module-level README.md files under each crate and run the project workspace from the top-level codex-rs directory so shared config, features, and build scripts stay aligned.