Skip to content

[Windows Sandbox] Setup fails when sandbox_mode is danger-full-access and cannot self-heal DACL on .sandbox-bin #49299

Open

Description

@andrew05060414

What version of Codex are you using?

Codex CLI 0.159.0 / Codex Desktop App (Windows)

What platform is your computer?

Windows 11 x64 (OS Build 26100)

What issue are you seeing?

When initiating Windows sandbox setup/repair from the Codex Desktop App or via the windowsSandbox/setupStart RPC, the setup process fails and halts indefinitely due to two distinct software defects:

1. Setup flow incorrectly couples with the active session's unmanaged permission profile

In windows_sandbox_processor.rs, windows_sandbox_setup_start reads config.permissions.effective_permission_profile() and forwards it into run_windows_sandbox_setup.
If the user currently has sandbox_mode = "danger-full-access" set in ~/.codex/config.toml (e.g. while testing or temporarily working around sandbox issues), ResolvedWindowsSandboxPermissions::try_from_permission_profile_for_workspace_roots bails with:

only managed permission profiles can be enforced by the Windows sandbox

Because the setup RPC is intended to provision the system-level sandbox infrastructure (creating CodexSandboxOffline/Online user accounts, setting up firewall rules, and preparing binary directories), it should not be aborted simply because the caller's current session configuration is unmanaged or unconstrained. This prevents users from ever setting up or fixing the sandbox once in full-access mode.

2. Setup helper lacks ownership/privilege fallback when locking .sandbox-bin

In codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs, lock_sandbox_dir() applies DACLs via SetNamedSecurityInfoW.
If ~/.codex/.sandbox-bin has inherited ACLs disabled or only grants Administrators modify access (M) without explicit WRITE_DAC permission, SetNamedSecurityInfoW returns OS error 5: Access is denied.
The elevated setup helper does not acquire SeTakeOwnershipPrivilege or reset the directory owner to Administrators before modifying DACL. Worse, it writes this fatal error report into .sandbox/setup_error.json. Subsequent checks read this file and display "Setup stopped / Failed to set up Windows sandbox", creating a persistent deadlock that cannot self-heal without manual user intervention (icacls + deleting setup_error.json).


What steps can reproduce the bug?

Scenario A (Unmanaged permission profile blocks setup):

  1. In ~/.codex/config.toml, configure:
    sandbox_mode = "danger-full-access"
  2. Start Codex Desktop or call the windowsSandbox/setupStart JSON-RPC method with { "mode": "elevated" }.
  3. Observe that setup immediately halts with error only managed permission profiles can be enforced by the Windows sandbox.

Scenario B (Broken DACL locks helper):

  1. On a machine where .sandbox-bin has modified DACLs lacking WRITE_DAC (or broken inheritance):
    icacls "$env:USERPROFILE\.codex\.sandbox-bin" /inheritance:r /grant:r "$($env:USERNAME):(OI)(CI)M" "Administrators:(OI)(CI)M"
  2. Run sandbox setup.
  3. The elevated helper fails at lock_sandbox_bin_dir with:
    lock sandbox bin dir ... failed: SetNamedSecurityInfoW sandbox dir failed: 5
    
  4. Setup writes .sandbox/setup_error.json, perpetually locking sandbox readiness.

What is the expected behavior?

  1. run_windows_sandbox_setup / setupStart should provision the sandbox environment using a default managed restricted profile (e.g., PermissionProfile::workspace_write()) when the current session's profile is unmanaged, allowing users to successfully configure or repair their sandbox from any state.
  2. The elevated setup helper should acquire ownership (OWNER_SECURITY_INFORMATION) or enable SeTakeOwnershipPrivilege/SeRestorePrivilege when encountering ERROR_ACCESS_DENIED during lock_sandbox_dir, ensuring robust self-healing of .sandbox-bin permissions.

Code References

  • Unmanaged profile coupling:
    • codex-rs/app-server/src/request_processors/windows_sandbox_processor.rs:80
    • codex-rs/core/src/windows_sandbox.rs:155 and L310
    • codex-rs/windows-sandbox-rs/src/resolved_permissions.rs:62-73
  • DACL locking failure:
    • codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs:382-395 (lock_sandbox_dir)
    • codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs:705-723 (lock_sandbox_bin_dir)

Suggested Fix Outline

  1. In codex-rs/core/src/windows_sandbox.rs:
    Normalize the profile during setup:
    let permission_profile = match &request.permission_profile {
        PermissionProfile::Managed {
            file_system: ManagedFileSystemPermissions::Restricted { .. },
            ..
        } => request.permission_profile,
        _ => PermissionProfile::workspace_write(),
    };
  2. In codex-rs/windows-sandbox-rs/src/bin/setup_main/win.rs:
    In lock_sandbox_dir, if SetNamedSecurityInfoW fails with error code 5 (ERROR_ACCESS_DENIED), elevate ownership to Administrators first via OWNER_SECURITY_INFORMATION (or enable SeTakeOwnershipPrivilege), then retry applying the DACL.

(Note: Per the repository's contributing guidelines stating external contributions are by invitation only, we are filing this comprehensive report first. We have verified the root causes locally and are glad to submit a PR if invited!)

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    sandboxIssues related to permissions or sandboxing
    app-serverIssues involving app server protocol or interfaces
    on Sep 29, 2026
  2. github-actions commented on Sep 29, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. Water-Run commented on Sep 30, 2026

    @Water-Run

    Confirming defect #2 from this report on Codex Desktop 26.928.1915.0 / codex-cli 0.159.2, with a verified workaround and one additional finding about why it cannot self-heal.

    Environment

    Codex App 26.928.1915.0 (AppX Status Ok)
    codex-cli 0.159.2 (npm)
    OS Windows 11 Pro for Workstations, build 26220 (Insider Preview), x64
    sandbox_mode workspace-write (unchanged throughout)
    [windows] sandbox elevated
    Service CodexSandboxService.OpenAI.Codex — Running / Automatic, PathName matches the installed package
    Sandbox accounts CodexSandboxOffline / CodexSandboxOnline both present, Enabled=True, both members of CodexSandboxUsers

    Config was not a factor: config.toml parse ok, no project-level .codex/config.toml, no profile layer, no ProgramData\OpenAI\Codex\config.toml, zero NUL bytes, no danger-full-access anywhere.

    The DACL state, exactly

    .sandbox-bin is the only one of the three generated sandbox directories carrying a protected DACL (SDDL D:PAI…) that dropped the inherited grant from .codex:

    .sandbox-bin        SYSTEM: Modify, Synchronize (explicit, IsInherited=False)          <-- no WRITE_DAC, no DELETE_CHILD
    .sandbox            SYSTEM: Modify, Synchronize (explicit) + FullControl (inherited)
    .sandbox-secrets    SYSTEM: Modify, Synchronize (explicit) + FullControl (inherited)
    

    As the interactive user every CreateFileW access on \\?\…\.sandbox-bin succeeds (including exclusive FILE_SHARE_NONE), so the failure is specific to the SYSTEM-token helper — consistent with SetNamedSecurityInfoW returning 5, since SYSTEM has Modify but not WRITE_DAC, and the helper takes no SeTakeOwnershipPrivilege fallback.

    Verified workaround

    Grant SYSTEM full control on that one directory only (non-recursive, no inheritance flags, non-admin — the interactive user holds ChangePermissions there):

    icacls "$env:USERPROFILE\.codex\.sandbox-bin" /grant "NT AUTHORITY\SYSTEM:(F)"
    codex sandbox whoami

    Observed result — setup then completes on the very next attempt:

    signal before after
    .sandbox\setup_marker.json 0 bytes (invalid) 267 bytes, {"version":5,…}
    .sandbox\setup_error.json {"code":"helper_sandbox_lock_failed"} absent
    codex doctor sandbox provisioning failed / error code helper_sandbox_lock_failed / 1 fail sandbox provisioning complete / 0 fail
    codex sandbox whoami — waterrun\codexsandboxoffline

    The log shows the failure always occurring after successful provisioning work, never before it:

    ensuring sandbox users offline=CodexSandboxOffline online=CodexSandboxOnline
    firewall rule configured … codex_sandbox_offline_block_loopback_udp / _tcp / _outbound / _inbound
    WFP setup succeeded for CodexSandboxOffline with 12 installed filters
    setup error: helper_sandbox_lock_failed: lock sandbox bin dir \\?\…\.sandbox-bin failed: open directory \\?\…\.sandbox-bin
    

    Additional finding: the workaround is self-defeating

    After the successful setup, Codex rewrites .sandbox-bin's DACL and removes the FullControl ACE that was just granted:

    after icacls : D:PAI(A;;FA;;;SY)(A;OICI;0x1301bf;;;SY)(A;OICI;0x1301bf;;;BA)…
    after setup  : D:PAI(          )(A;OICI;0x1301bf;;;SY)(A;OICI;0x1301bf;;;BA)…   <-- (A;;FA;;;SY) gone
    

    So the directory is returned to the exact state that made the lock step fail. Setup only escapes the loop while setup_marker.json stays valid, because Codex then skips re-provisioning entirely. Any event that invalidates the marker (marker missing/incompatible, a desired_ports change, a version bump that changes the marker schema) puts the system straight back into helper_sandbox_lock_failed with no way to self-heal. This suggests the lock step needs the same owner/privilege fallback already proposed above, and/or that the post-setup DACL normalization should preserve WRITE_DAC for SYSTEM.

    Trigger correlation

    Failures began within minutes of an automatic app update. All 22 occurrences are from one day; this error code never appears in the retained sandbox logs before it:

    • codex-windows-sandbox-service.exe, codex-windows-sandbox-setup.exe — written 09:20:34
    • Desktop-bundled codex.exe — written 09:20:40
    • new …\OpenAI\Codex\bin\* runtime dirs — created 09:26:28 / 09:26:31
    • first helper_sandbox_lock_failed — 09:27:01, last 09:35:19 (Desktop re-issuing windowsSandbox/setupStart on every turn, per logs_2.sqlite)

    One clarification that may be causing misdiagnosis

    Several reports note the Composer still shows Full Access even though config.toml says sandbox_mode = "workspace-write". That is not a config-precedence problem and no config layer needs changing. When elevated provisioning fails, Codex falls back to an unrestricted permission profile for the session and surfaces the setup banner. The related node_repl warning env var CODEX_WINDOWS_REGISTERED_CORE is not set is likewise a symptom of the missing registration, not the cause. There is no project-level .codex/config.toml, profile layer, or ProgramData config on this machine that overrides anything.

    Cheap self-diagnosis

    (Get-Acl "$env:USERPROFILE\.codex\.sandbox-bin").GetSecurityDescriptorSddlForm('Access')

    A leading D:PAI (protected, inheritance disabled) combined with SYSTEM at 0x1301bf (M) and no FA entry is the signature of this failure.

  4. spidikor commented on Oct 1, 2026

    @spidikor

    Adding a narrower local result for the directory ACL issue (defect 2). This doesn't establish a fix for the separate unmanaged-permission-profile failure.

    On Codex Desktop 26.928.2636.0 / Windows 11 Home, build 26300, the service was running as LocalSystem, while SYSTEM had Modify but lacked WRITE_DAC on the protected .sandbox-bin directory.

    After saving the DACL and checking that the path wasn't redirected, I added only SYSTEM's WRITE_DAC, additively on that directory itself, and retried the normal setup. Actual sandbox PowerShell commands then exited 0, and workspace/ACL reads worked! Ownership, Administrators' rights and the sandbox user group's rights stayed unchanged.

    Full anonymized steps, backup/path checks, and source comparison.

    The catch: Codex removed the temporary permission afterward. Shell startup and reads were verified; workspace writes, an upgrade and another provisioning cycle weren't. So this is a temporary workaround for the matching LocalSystem/ACL case, with recurrence still possible.

  5. Isajunsei commented on Oct 2, 2026

    @Isajunsei

    Additional October 2 report for the setup/profile part of this issue.

    On Windows 11 with desktop package 26.930.2377.0 and bundled command runner 0.159.0-alpha.12.1, our repair record confirms that setup stopped while the active configuration was danger-full-access, with:

    only managed permission profiles can be enforced by the Windows sandbox
    

    Provisioning succeeded when the setup invocation alone used workspace-write, without permanently changing config.toml. Subsequent desktop commands succeeded.

    We also saw helper_sandbox_lock_failed / open directory errors earlier. WRITE_DAC and ownership changes were not a durable resolution in our case, so we are not claiming confirmation of the separate SetNamedSecurityInfoW/DACL scenario or recommending that workaround.

    A later recurrence was independently traced to two CODEX_HOME roots sharing the machine-wide sandbox accounts; the additional report is in #40627.

    We checked current source after the runtime incident. #47922 already handles full-access provisioning through registered Core, while the legacy full-access rejection remains an explicit regression-test expectation. We have not established which exact registration/setup path our installed app took and have not reproduced this against a fresh build of current main. The useful remaining question is whether the app's setup/repair flow can enter that rejecting legacy/initial-provisioning path, and whether it can report that distinction clearly rather than repeatedly offering setup that immediately fails.

  6. MaxMiksa commented on Oct 3, 2026

    @MaxMiksa
    Contributor

    Confirming the unmanaged-permission-profile setup failure on October 3 with a newer installed runtime:

    • Windows 11 x64
    • Desktop MSIX package: OpenAI.Codex 26.930.3930.0
    • Desktop runtime used for the direct app-server reproduction: codex-cli 0.160.0

    The app showed “设置 Windows 以继续” / “更新 Agent 沙盒以继续” (“Set up Windows to continue” / “Update Agent sandbox to continue”). Repeatedly clicking setup/update and fully restarting the app did not resolve the send blocker.

    Relevant existing user configuration:

    approval_policy = "never"
    sandbox_mode = "danger-full-access"
    
    [windows]
    sandbox = "elevated"

    A direct stdio app-server probe using that configuration reproduced:

    windowsSandbox/readiness
    => {"status":"updateRequired"}
    
    windowsSandbox/setupStart {"mode":"elevated","cwd":"<existing workspace>"}
    => {"started":true}
    
    windowsSandbox/setupCompleted
    => {"mode":"elevated","success":false,"error":"only managed permission profiles can be enforced by the Windows sandbox"}
    

    Observed recovery: launch a separate app-server with an invocation-only override:

    codex -c 'sandbox_mode="workspace-write"' app-server --stdio

    Then initialize the connection and call windowsSandbox/setupStart with mode: "elevated" and the existing workspace as cwd. This got past the immediate permission-profile rejection without permanently changing the user's full-access configuration. A subsequent fresh app-server probe under the original configuration returned {"status":"ready"}, and the desktop user confirmed that the prompt disappeared and messages could be sent again.

    Verification limits: the setup helper was still running when last checked, so this reports restored readiness and desktop message sending, not a captured successful setupCompleted notification or a complete sandbox isolation test. An older helper_sandbox_lock_failed record also existed before this attempt, but we did not manually edit ACLs or establish that the separate DACL defect caused the current immediate failure.

    Please ensure the desktop setup/update entry point can provision the sandbox when the existing configuration is full access, and surface the actual setup failure instead of repeatedly offering an update that fails immediately. This confirms the installed-runtime behavior; it does not establish whether current main or the registered-Core path already fixes it.

  7. labolabo commented on Oct 4, 2026

    @labolabo

    Additional finding for the permission-profile part (defect 1). Desktop 26.930.2377.0 (bundled codex 0.159.0-alpha.12.1), Windows 11 Pro.

    Changing sandbox_mode to workspace-write in the user config (~/.codex/config.toml) was NOT enough for us. Retry setup still failed immediately with:

    only managed permission profiles can be enforced by the Windows sandbox
    

    Cause: the workspace that was open in Desktop had its own project-level .codex/config.toml with sandbox_mode = "danger-full-access". windowsSandbox/setupStart loads config for the cwd passed in the request (load_setup_config -> load_for_cwd -> load_config_layers_state, which includes project layers for trusted projects), and Desktop appears to pass the open workspace as that cwd (setup failed with the project open and succeeded from a folder with no project config), so the project layer wins over the user layer.

    What worked:

    1. Move %USERPROFILE%\.codex\.sandbox-bin aside and recreate it as an empty folder (defect 2; same approach as Windows elevated sandbox re-provisioning fails on previously locked .sandbox-bin ACL after upgrade #46380)
    2. Quit Desktop, set user config sandbox_mode = "workspace-write" temporarily
    3. In Desktop, add/open an empty folder that has no .codex/config.toml, then Retry setup -> setup succeeded (success message shown, setup_marker.json written, setup_error.json gone)
    4. Restore danger-full-access

    After success, .sandbox-bin was re-locked with SYSTEM:(M) only (no WRITE_DAC), so defect 2 will likely recur on the next re-provision.

    Suggestion: besides provisioning with a managed profile regardless of the active one, the setup error should say which config layer (project vs user) supplied the rejected profile; otherwise users who fix ~/.codex/config.toml cannot tell why Retry still fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingsandboxIssues related to permissions or sandboxingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions