Skip to content

Windows: /codex:rescue --write workspace-write gets empty workspace_roots, causing ACCESS_DENIED #421

Description

@Emes13

Windows: /codex:rescue --write workspace-write gets empty workspace_roots, causing ACCESS_DENIED

Summary

On Windows, /codex:rescue --write runs from the Claude Code Codex plugin can fail to write to the trusted repository root even though the run is explicitly write-capable and launched from that repo.

This may ultimately belong in openai/codex, but I am filing it against openai/codex-plugin-cc because the reproducible path is the plugin's rescue flow, which launches Codex through app-server/unified-exec.

The sandboxed process can read the workspace, but writes fail with ACCESS_DENIED under the CodexSandboxOffline identity. Inspecting the restricted token from inside the failing run shows that the workspace capability SID for the repo is missing from TokenRestrictedSids; only the TEMP-related capabilities survive.

This appears to be a materialization bug in the new symbolic workspace roots model: the sandbox profile carries a symbolic :workspace_roots entry, but the Windows backend receives an empty workspace_roots list from the unified-exec/app-server path, so the symbolic entry materializes to nothing.

(This issue was researched extensively using Claude Fable 5 and then summarized by ChatGPT 5.5-high running in Codex CLI.)

Environment

  • Codex CLI: codex-cli 0.142.5
  • OS: Windows 11 Home, 64-bit
  • Windows version: 10.0.26200, build 26200
  • PowerShell: 5.1.26100.8655
  • Route: Claude Code official OpenAI Codex plugin rescue flow, using /codex:rescue --write through Codex app-server / unified-exec
  • Plugin version observed locally: openai-codex/codex/1.0.5
  • Repo root:
    • C:\Users\moshe\Claude\Kav
    • git rev-parse --show-toplevel returns C:/Users/moshe/Claude/Kav
  • Codex config includes:
    • sandbox_mode = "danger-full-access"
    • [windows] sandbox = "elevated"
    • [projects.'c:\users\moshe\claude\kav'] trust_level = "trusted"

Important note: the failing runs were not the default read-only rescue runs. They were explicitly write-capable workspace-write runs.

Actual Behavior

A /codex:rescue --write / workspace-write run launched through the plugin/app-server path can read files in the workspace but fails to write to the workspace with ACCESS_DENIED.

The failing sandbox identity is CodexSandboxOffline.

Dumping the sandbox token's TokenRestrictedSids from inside a failing run showed that the Kav workspace capability SID was absent. The token had only four restricted SIDs and none corresponding to the repo root. TEMP remained writable.

Expected Behavior

For a trusted repo launched from the repo root, workspace-write should materialize the active workspace root into the Windows sandbox token so writes under the repo root succeed, while protected areas such as .git remain protected.

If workspace_roots is empty in the app-server/unified-exec path, it should fall back to the cwd/repo root the same way the non-unified path appears to do.

Evidence / Diagnostics

  • The run was launched from C:\Users\moshe\Claude\Kav.
  • Git root resolved correctly.
  • The repo is marked trusted in Codex config.
  • Reads from the workspace succeeded.
  • Writes to the workspace failed with ACCESS_DENIED.
  • Token dump from inside the sandbox showed the workspace capability SID was missing from TokenRestrictedSids.
  • Adding an explicit ACL ACE for CodexSandboxOffline on C:\Users\moshe\Claude\Kav fixed the same rescue pipeline without changing plugin flags, Codex config, cwd, or trust settings.

That last point seems decisive: this does not appear to be the plugin merely launching Codex in read-only mode. If it were, the ACL change would not have fixed the failure.

Suspected Cause

Codex's symbolic workspace roots model appears to depend on a workspace_roots list being passed to the Windows sandbox backend.

In workspace-write, the profile carries a symbolic :workspace_roots entry. In this app-server/unified-exec route, the Windows backend receives an empty workspace_roots list, so :workspace_roots materializes to no repo write capability.

There appears to be an empty-list fallback in core/src/exec.rs that uses cwd when no workspace roots are supplied, but the unified-exec/app-server path appears to pass the empty list through without applying the same fallback. The suspect area is unified_exec/process_manager.rs.

A legacy writable_roots config override did not fix the issue, likely because it feeds the same materialization path that is receiving or preserving the empty workspace roots list.

Workaround

Adding an explicit Windows ACL entry for CodexSandboxOffline on the workspace root allowed writes to work through the same real rescue/app-server pipeline. This is only a workaround; the sandbox token still appears not to receive the expected workspace capability SID.

Related Issues Checked

In openai/codex-plugin-cc, the closest issue I found was:

This report is different because the failing runs were explicitly --write / workspace-write, and the diagnostic evidence points to the Windows sandbox token missing the workspace capability SID rather than the plugin simply launching a read-only run.

In openai/codex, nearby but not identical issues included:

  • #24214
  • #26737
  • #29867

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions