openai / openai/codex

[Windows] Elevated sandbox re-provisions unconditionally every session and never persists the rotated credentials, causing a UAC prompt per session

Open
#42,213 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI sandbox windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description


What version of Codex are you using?

@openai/codex 0.151.0 (npm global), codex.exe app-server --listen stdio://.
Also reproduced against the same CODEX_HOME shared with Codex Desktop
(OpenAI.Codex_26.820.9563.0) and the VS Code extension (openai.chatgpt-26.825.51511).

Verified that codex-rs/windows-sandbox-rs is unchanged in 0.152.1 and 0.153.0-alpha.5 —
the only commit touching that crate since rust-v0.151.0 is 84aa7520, which modifies
sandbox_smoketests.py only. So this should reproduce on current latest.

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Pro). Single local account, member of
BUILTIN\Administrators, UAC enabled (EnableLUA=1, ConsentPromptBehaviorAdmin=5,
PromptOnSecureDesktop=0). ~/.codex/config.toml contains [windows] sandbox = "elevated".

What issue are you seeing?

Every new Codex session re-provisions the elevated Windows sandbox, which raises a UAC
consent prompt. Because the process runs under a UAC-filtered admin token, the prompt is
interactive and cannot be satisfied by an unattended agent runner, so the session executes
zero commands.

Critically: a fully successful codex sandbox setup --elevated does not stop this. The
next session re-provisions within ~60 seconds, rotating the sandbox account passwords while
leaving .sandbox-secrets/sandbox_users.json and .sandbox/setup_marker.json untouched. The
persisted credentials therefore go stale immediately and the loop is self-sustaining.

This looks related to, but distinct from, #35841 (there the credentials cannot be decrypted at
all — CryptUnprotectData 0x8009000B). Here the setup path succeeds and simply does not write
the rotated credentials back. #27944 ("recover stale Windows sandbox credentials") appears to
be the mechanism intended to prevent this; it is not holding.

What steps can reproduce the bug?
  1. Windows 11, single UAC-filtered admin account, [windows] sandbox = "elevated".
  2. Close every other Codex surface (desktop app, VS Code extension, interactive CLI) so one
    CODEX_HOME has exactly one consumer. Note that the desktop app supervisor ChatGPT.exe
    respawns codex.exe if only the child is killed — stop the supervisor.
  3. Record PasswordLastSet for CodexSandboxOffline / CodexSandboxOnline, and the mtimes of
    .sandbox/setup_marker.json and .sandbox-secrets/sandbox_users.json.
  4. From an elevated shell run:
    codex sandbox setup --elevated --current-user --codex-home <CODEX_HOME>
    Confirm it exits 0 and that the marker, the credential file, and a current-day
    .sandbox/sandbox.<date>.log are all freshly written and mutually consistent.
  5. Start a new Codex session (any surface) against that CODEX_HOME.
  6. Re-read the same values.
What is the expected behavior?

After a successful elevated setup, a new session should reuse the persisted sandbox
credentials and require no further elevation until the marker is genuinely invalid.

Actual behavior

Observed 2026-09-01 on a single machine, all timestamps local (UTC+2):

21:11:45.589  elevated `codex sandbox setup --elevated --current-user --codex-home ...`
21:11:46.749  exit 0 — "Windows elevated sandbox setup completed for <user> at <CODEX_HOME>"

Post-setup state — all four artifacts fresh and mutually consistent:
  setup_marker.json    21:11:46.728  created_at 2026-09-01T19:11:46.728590+00:00
  sandbox_users.json   21:11:45.765
  .sandbox/sandbox.2026-09-01.log  21:11:46, 1421 bytes, ending
    "WFP setup succeeded for CodexSandboxOffline with 12 installed filters"
    "setup provisioning binary completed"
  PasswordLastSet      21:11:45      <-- same second as the credential-file write

21:12:30      next Codex session starts
21:12:45      *** PasswordLastSet -> 21:12:45
              setup_marker.json    STILL 21:11:46.728   (not rewritten)
              sandbox_users.json   STILL 21:11:45.765   (not rewritten)
21:21:00      *** PasswordLastSet -> 21:21:00
              marker and credential file STILL unchanged

21:23:58      fresh session, no other Codex surface running, nothing killed by the operator
21:24:16      consent.exe (UAC prompt), parent = svchost.exe hosting Appinfo
              prompt not accepted ->
                codex-windows-sandbox-setup.exe spawns:      0
                CodexSandboxOnline.LastLogon:                did not advance
                CodexSandboxOffline.LastLogon:               did not advance
                tool calls executed by the session:          0

The blocked session reported: "even a read-only local file read cannot start through the
terminal".

The successful setup at 21:11:45/46 was undone 59 seconds later by the next session.

Additional information

Elevation is caller-driven. codex-windows-sandbox-setup.exe is manifested
requestedExecutionLevel="asInvoker" and takes a single positional base64 payload (passing
--help returns helper_request_args_failed: failed to decode payload b64: Invalid symbol 45, offset 0). Codex elevates it via the runas verb, so every re-provision is a consent prompt.
Confirmed: every consent.exe observed had svchost.exe (Application Information service) as
its parent, and every helper process was a direct child of a codex.exe app-server.

Measured over a longer window, with every non-agent Codex surface stopped, two consecutive
agent sessions produced 15 consent.exe instances, 9 helper spawns and 5 password rotations,
with the marker and credential file never once rewritten.

Consequences beyond the prompt:

  1. Unattended/CI/agent-runner use of Codex on Windows with sandbox = "elevated" is not
    possible — every session blocks on an interactive prompt.
  2. net accounts shows lockout threshold 10 / 10-minute window on a default workstation.
    Repeated failed logons with stale stored credentials risk locking CodexSandboxOffline /
    CodexSandboxOnline, after which Codex fails even when the prompt is accepted.
  3. Concurrent sessions invalidate each other. The sandbox accounts are machine-global, so a
    second session rotating them drags an already-provisioned first session into
    re-provisioning. Observed directly: a session that had been stable for 15 minutes across 70
    tool calls spawned a setup helper immediately after a newer session rotated the accounts.
    A separate CODEX_HOME does not isolate this, because the SAM accounts are not per-home.
Separate security observation (happy to split into its own report)

The elevation target is writable by the principals it is meant to contain:

...\codex-win32-x64\vendor\x86_64-pc-windows-msvc\codex-resources\codex-windows-sandbox-setup.exe
  <HOST>\<user>:(I)(F)
  <HOST>\CodexSandboxUsers:(I)(M)      <-- the sandbox accounts have Modify on the binary
                                       that later runs as Administrator

A process running inside the sandbox can modify the binary that a subsequent elevation will
execute with administrator rights. Recommend tightening the shipped ACL so CodexSandboxUsers
has no write access to codex-resources\.

(Account names above are the Codex-created defaults on a single test host; machine SIDs are omitted; no credentials or DPAPI
material are included.)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in codex-rs/windows-sandbox-rs and trace the elevated setup entry point, including codex-windows-sandbox-setup.exe and writes to .sandbox-secrets/sandbox_users.json and .sandbox/setup_marker.json. Review sandbox_smoketests.py and reproduce the setup-then-new-session sequence on Windows. Done means a valid setup is reused without rotating credentials or prompting for UAC again.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
operating-systems, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.