[Windows] Elevated sandbox re-provisions unconditionally every session and never persists the rotated credentials, causing a UAC prompt per session
Nobody has claimed this yet.
- 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?
- Windows 11, single UAC-filtered admin account,
[windows] sandbox = "elevated". - 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 supervisorChatGPT.exe
respawnscodex.exeif only the child is killed — stop the supervisor. - Record
PasswordLastSetforCodexSandboxOffline/CodexSandboxOnline, and the mtimes of
.sandbox/setup_marker.jsonand.sandbox-secrets/sandbox_users.json. - 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>.logare all freshly written and mutually consistent. - Start a new Codex session (any surface) against that CODEX_HOME.
- 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:
- Unattended/CI/agent-runner use of Codex on Windows with
sandbox = "elevated"is not
possible — every session blocks on an interactive prompt. net accountsshows lockout threshold 10 / 10-minute window on a default workstation.
Repeated failed logons with stale stored credentials risk lockingCodexSandboxOffline/
CodexSandboxOnline, after which Codex fails even when the prompt is accepted.- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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