Windows elevated sandbox can stall for minutes loading a user profile per command
Environment
- Codex CLI:
0.144.5(current npmlatestwhen reproduced on 2026-07-18) - OS: Windows 11 Core,
10.0.26200, x64 - Sandbox: native Windows elevated sandbox
- Model: independent; the delay occurs before the requested command starts
- Terminal: PowerShell-based launcher; also reproduces with standalone
codex sandbox codex doctor --json: not attached because a host invocation did not return within 120 seconds
Problem
Every elevated-sandbox command launches codex-command-runner with CreateProcessWithLogonW(..., LOGON_WITH_PROFILE, ...). This synchronously loads the sandbox account's registry profile even though the runner does not consume that account's HKCU state.
On a healthy machine this adds only a fraction of a second. After sustained multi-session activity, the same call can block for minutes. During an observed stall:
- the parent was blocked inside
CreateProcessWithLogonWbefore Codex reached its 15-second runner pipe timeouts; - Windows Wait Chain Traversal showed a wait through
\\RPC Control\\SECLOGON; - User Profile Service logged repeated loads of the sandbox account's
ntuser.datandUsrClass.dathives; - ordinary host commands remained fast;
- rebooting temporarily restored sub-second launches, but stock Codex continued loading a profile for every command.
This affects shell commands and native filesystem/apply-patch operations because they share the runner-launch path. Concurrent Codex sessions multiply the unnecessary profile loads; when Secondary Logon/User Profile Service becomes contended, a trivial command can wait for minutes even though the command and workspace drive are healthy.
The call is visible on current main here:
Microsoft documents that LOGON_WITH_PROFILE loads the user's profile and that profile loading is time-consuming:
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw
Reproduction
- Provision the native elevated sandbox:
``toml``
[windows]
sandbox = "elevated"
- Enable
Microsoft-Windows-User Profile Service/Operationaland record its latest event ID. - From a trusted workspace, run:
``powershell``
codex sandbox -c 'windows.sandbox="elevated"' -P :workspace -C $PWD -- cmd.exe /d /c "echo CODEX_SANDBOX_PROFILE_REPRO"
- Query new events containing
CodexSandboxOffline. - Repeat the command.
On stock 0.144.5, each command deterministically produces two event ID 5 hive-load events plus one event ID 67 profile event. The minutes-long contention is intermittent, but the unnecessary profile load occurs on every invocation.
Controlled evidence
I ran the same harmless echo command sequentially through stock 0.144.5 and a side-by-side patched build from current main, using the already-provisioned offline sandbox account to isolate events from other sessions.
| Runner | Successful runs | Exact output | Offline profile events |
| --- | ---: | --- | ---: |
| Stock 0.144.5 | 5/5 | CODEX_SANDBOX_OFFLINE_AB_OK | 15: exactly 3 per run |
| Patched current main | 5/5 | CODEX_SANDBOX_OFFLINE_AB_OK | 0 |
Stock latency was 240–277 ms and patched latency was 243–313 ms on the healthy post-reboot system. This is not presented as a healthy-state microbenchmark improvement: the material result is eliminating the operation captured blocking for minutes under contention.
Both builds also returned identical exit codes and child environment values, including an explicit IPC-propagated variable and USERPROFILE.
An otherwise equivalent direct Win32 call using the existing sandbox credential in memory with dwLogonFlags = 0 launched cmd.exe /c exit 0 in 57.81 ms, returned 0, and generated zero profile events. No credential was printed, persisted, or changed.
Proposed fix
Stop requesting the sandbox user's profile for the runner:
-use windows_sys::Win32::System::Threading::LOGON_WITH_PROFILE;
+const RUNNER_LOGON_FLAGS: u32 = 0;
- LOGON_WITH_PROFILE,
+ RUNNER_LOGON_FLAGS,
Why this appears safe:
- the runner's environment pointer is already null, so it inherits the caller environment;
- the requested child environment is carried in
SpawnRequest.envand explicitly passed to child creation; - the runner has no HKCU access; its only
USERPROFILEuse treats the inherited value as a filesystem location for the CWD junction; - patched online/offline and multi-root sandbox commands preserved output, exit status, environment propagation, credentials, and restrictions.
Validation
- Full side-by-side Codex CLI and both Windows helpers built successfully from current
main. just fix -p codex-windows-sandboxandjust fmtpassed.- Focused crate tests: 131 passed. One legacy test failed and one timed out; both reproduced identically on untouched
35eaf3ffb0bf2001486c68c47a3d946b34d16634, so they predate and do not exercise this elevated-runner change. - Five isolated stock and five patched integration runs produced identical command behavior; profile events changed from 3 per stock run to 0 per patched run.
This is distinct from #18620, which concerns logon error codes, and #14585, which concerns ACL/path behavior.
Is loading the sandbox account's HKCU profile intentional for a dependency not visible in the current runner? If not, I have an atomic one-file implementation ready. Please explicitly invite a PR if this approach aligns with the intended architecture and you would like the patch submitted.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I can confirm this independently on an affected Codex Windows desktop installation.
Environment
26.707.3748.0Minimal benchmark
Exact command:
Observed end-to-end tool latency:
| Windows sandbox setting | Run 1 | Run 2 |
| --- | ---: | ---: |
|
[windows] sandbox = "elevated"| 31.9 s | 35.9 s ||
[windows] sandbox = "unelevated"| 0.3 s | — |All runs returned exit code 0. Changing only the Windows sandbox implementation removed more than 99% of the latency. This makes the elevated implementation unusable for normal agent work because the cost is paid on every small command.
Windows event correlation
On the affected elevated path, the end of the blank interval correlates with Security Event 4624 containing:
LogonType = 2AuthenticationPackageName = NegotiateLogonProcessName = seclogoTargetUserName = CodexSandboxOfflineProcessName = C:\Windows\System32\svchost.exeThe process sequence observed locally is consistent with Codex starting
codex-command-runner.exeasCodexSandboxOfflinethroughCreateProcessWithLogonW, with the command not beginning until the Secondary Logon path completes.This event correlation does not, by itself, prove that the entire 30–50 second interval is specifically a Kerberos-to-NTLM fallback. That would require DNS/Kerberos ETW or a network trace. Profile loading, Secondary Logon/User Profile Service contention, or another operation inside the same logon path remain possible contributors. It does, however, strongly support the central finding in this issue: the delay is in the elevated cross-user runner launch, not in the requested command or workspace I/O.
Impact and requested behavior
A security boundary that adds 30–50 seconds to every command is effectively unavailable to users, so they are forced onto the weaker
unelevatedfallback.In addition to removing unnecessary
LOGON_WITH_PROFILEuse if it is not required, please consider:CreateProcessWithLogonW/ Secondary Logon latency;unelevatedwhen elevated startup exceeds a reasonable threshold;cmd.exe /d /c exit 0startup latency.The
unelevatedworkaround is effective here, but the current default preference forelevatedmakes this performance failure especially damaging.