Windows (elevated sandbox): approved escalated command still runs inside the sandbox in the CLI, works in Codex Desktop

Open 💬 0 comments Opened Aug 27, 2026 by Tempestline

Summary

On native Windows with [windows] sandbox = "elevated", when the model requests an escalated
command (exec_command with sandbox_permissions: "require_escalated" + prefix_rule) and the
guardian reviewer approves it, the terminal CLI (codex, client codex-tui) executes the command
inside the sandbox anyway
(as the CodexSandboxOffline/Online user). The Codex Desktop app
handles the identical request correctly and runs it outside the sandbox.

Result in the CLI: every command that needs the user's credentials fails —
ghAccess is denied reading %APPDATA%\GitHub CLI\config.yml;
ssh <ssh-alias>hostname could not be resolved (SSH config/known_hosts in the profile are invisible);
git fetch over HTTPS → SEC_E_NO_CREDENTIALS.

Environment

  • Windows 11 Home, 10.0.26200
  • Codex Desktop (Microsoft Store) 26.820.9563.0, bundled runtime codex-cli 0.150.0-alpha.8
  • Codex CLI (npm @openai/codex) 0.149.0 — same behaviour observed by the user on 0.150.x before downgrading
  • gh 2.94.0, OpenSSH (Windows built-in)
  • ~/.codex/config.toml (relevant part):

approval_policy = "on-request"
approvals_reviewer = "guardian_subagent"
sandbox_mode = "workspace-write"
sandbox_workspace_write.network_access = true
[windows]
sandbox = "elevated"

  • ~/.codex/rules/ is empty (verified; earlier presence of rules files made no difference to this bug).
  • Sandbox users CodexSandboxOffline / CodexSandboxOnline exist; sandbox audit passes.

Steps to reproduce

  1. In a project folder, run codex in PowerShell (terminal CLI).
  2. Ask: "Run gh auth status and ssh <host> date -u; escalate if needed."
  3. The model calls

exec_command({cmd:"gh auth status", sandbox_permissions:"require_escalated", justification:"…", prefix_rule:["gh","auth","status"]}).

  1. The guardian reviewer runs (several codex-auto-review turns) and approves.
  2. Observe: the command still executes via the sandbox runner and fails with Access is denied for

GitHub CLI\config.yml; SSH fails with unresolved host alias.

Same steps in Codex Desktop (same machine, same config, same request shape) → command runs
outside the sandbox and succeeds (gh api …, gh pr view … worked at 2026-08-27 13:05–13:18Z).

Evidence (from ~/.codex/logs_2.sqlite and ~/.codex/.sandbox/sandbox.2026-08-27.log)

| thread | client (app_server.client_name) | threads.source | cli_version | result |
|---|---|---|---|---|
| 01a0434a-c8e3-7443-ad7a-b0e1c6809969 | Codex Desktop | vscode | 0.150.0-alpha.8 | escalated gh api … succeeded |
| 01a04372-bab9-7f60-9cc6-9db4fe0ef372 | codex-tui | cli | 0.149.0 | escalated git fetch, gh auth status, ssh … all failed |
| 01a0438b-7f6b-70e1-80cc-6419db84bda5 | codex-tui | cli | 0.149.0 | escalated gh auth status, ssh … failed |

  • For the failing threads, each escalated call is followed within ~2 s by guardian

(model=codex-auto-review) turns (2–7 per call), i.e. the approval path ran.

  • The sandbox log then shows the command being launched through the sandbox helper

(setup refresh: spawning …codex-windows-sandbox-setup.exe, helper launch resolution: using
copied command-runner path …codex-command-runner-0.149.0.exe
, then
START: …powershell.exe -NoProfile -Command …) — i.e. still sandboxed after approval.

  • Effective turn policy for the CLI threads (from feedback_tags):

approval_policy=OnRequest sandbox_policy=WorkspaceWrite { writable_roots: [], network_access: false … }
— note network_access: false although config sets sandbox_workspace_write.network_access = true;
the desktop thread shows network_access: true and a populated writable_roots.

  • No .rules file involved: exec_policy … loaded rules from 0 files.

Expected

After the guardian (or user) approves a require_escalated request, the CLI should run the command
outside the Windows sandbox with the user's profile, exactly as Codex Desktop does.

Workarounds found

  • Use Codex Desktop for anything needing credentials (escalation works there).
  • Or start the CLI with codex --sandbox danger-full-access for that session.

Extra observations (may be separate issues)

  1. A prefix_rule with decision = "allow" in ~/.codex/rules/default.rules (as written by the

desktop app's "Always allow") causes the command to skip approval and run inside the sandbox
— so an "always allow" for gh auth status permanently breaks gh on Windows. A decision = "prompt"
rule behaves the same way after approval.

  1. deny_read_acl_state.json in ~/.codex/.sandbox/ can be corrupted when two threads start at the

same time (two writers; file ends up as {"principals": {}} followed by a second JSON tail), after
which every new thread fails with helper_unknown_error: apply deny-read ACLs.

  1. With a permission profile containing "**/.env*" = "deny" in a workspace of ~800k files, every

thread start scans the whole tree (10+ min at 100% CPU), which starves the app-server request queue
(app_server_client_request_queue_rejected) and blanks the desktop UI.

View original on GitHub ↗