[Windows] Sandbox: Access denied on existing workspace descendants after sandbox SID change
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.908.40834
What subscription do you have?
ChatGPT Pro (5x)
What platform is your computer?
Win32NT 10.0.19045.0 Microsoft Windows NT 10.0.19045.0 10.0.19045.0 True
What issue are you seeing?
Summary
After a Codex sandbox re-initialization changed the sandbox user's SID, the sandbox lost write access to files inside existing subdirectories of the workspace. Codex cannot patch, edit, or generate code in any project with an established file tree.
Symptoms
- Codex reports PermissionError: [WinError 5] Access is denied when writing to existing files.
- The apply_patch tool reports "path contains a reparse point" — this is a false positive, verified with fsutil reparsepoint query, which returns "The file or directory is not a reparse point".
- The failure is reproducible for the entire subtree of apps/api/app, while apps/api (parent) and apps/web/src work fine.
Environment
- OS: Windows 10 (10.0.19045.0 x64)
- Codex App (Windows), version 26.908.40834
- Subscription: ChatGPT Pro
- Sandbox user (whoami): desktop-583kd57\codexsandboxoffline
- Sandbox user current SID: S-1-5-21-1747488710-827246756-3187947173-1006
Diagnostics
- whoami returns desktop-583kd57\codexsandboxoffline.
- The current sandbox user's SID (resolved from whoami via NTAccount.Translate) is S-1-5-21-1747488710-827246756-3187947173-1006.
- icacls on apps/api and apps/api/app both show the group CodexSandboxUsers with inheritable (OI)(CI)(M).
- However, the sandbox user's current SID is present in apps/api's ACL but absent from apps/api/app's ACL, despite inheritable ACEs on the parent.
- AreAccessRulesProtected is False on both paths, so inheritance is not blocked at the ACL level.
- Reboot did not resolve the issue.
- Manually granting the current SID resolves it permanently for that path (212 files updated, 0 failed).
Steps to Reproduce
- Set up Codex on Windows with the default sandbox.
- Work in a repository with an existing directory structure and files.
- Force a sandbox re-initialization (app update, or sandbox state reset).
- In Codex, attempt to edit any file under apps/api/app/mirigdkp_api/.
- The write fails with Access is denied.
Expected Behavior
The sandbox should either:
- recursively repair ACLs on all existing workspace files when the SID changes, or
- fail loudly at startup with an actionable error, or
- automatically request elevated permission to repair ACLs when it detects the sandbox user cannot write.
Currently none of these happen: Codex silently loses the ability to edit parts of the workspace, and the only fix is a manual icacls command run by the user.
Workaround
Run elevated PowerShell and execute:
icacls "C:\path\to\workspace\subdir" /grant "*S-1-5-21-1747488710-827246756-3187947173-1006:(OI)(CI)(M)" /t /c /q
This restores write access until the next sandbox SID change.
Related Issues
- #15165 (Windows elevated sandbox does not recursively grant usable ACLs to existing workspace files)
- #28943 (Fix Windows sandbox runtime ACL refresh) — fixed runtime binaries but not workspace descendants.
What steps can reproduce the bug?
-
Set up Codex on Windows with the default elevated sandbox, working in a repository with an existing directory tree and existing files (e.g. C:\MiriGDKPv2\apps\api\app\mirigdkp_api).
-
Use Codex normally for several sessions. Writes work fine at first.
-
Trigger a sandbox re-initialization. Any of these does it:
- Codex App update
- Rebooting Windows
- Sandbox state reset
-
In a new Codex session, ask it to edit a file inside an existing subdirectory, for example:
apps/api/app/mirigdkp_api/api/epoch_lifecycle.py -
Codex reports:
- PermissionError: [WinError 5] Access is denied
- apply_patch: "path contains a reparse point"
(the reparse point message is a false positive — fsutil reparsepoint query returns "The file or directory is not a reparse point")
-
Reproduce the boundary with manual commands in PowerShell:
Set-Content "C:\MiriGDKPv2\apps\api__test.tmp" -Value "x"
Remove-Item "C:\MiriGDKPv2\apps\api__test.tmp"
-> succeedsSet-Content "C:\MiriGDKPv2\apps\api\app__test.tmp" -Value "x"
Remove-Item "C:\MiriGDKPv2\apps\api\app__test.tmp"
-> Access is deniedSet-Content "C:\MiriGDKPv2\apps\web\src__test.tmp" -Value "x"
Remove-Item "C:\MiriGDKPv2\apps\web\src__test.tmp"
-> succeeds -
Confirm the SID boundary with icacls:
icacls "C:\MiriGDKPv2\apps\api" | Select-String "1747488710-827246756-3187947173"
-> the sandbox user's current SID is presenticacls "C:\MiriGDKPv2\apps\api\app" | Select-String "1747488710-827246756-3187947173"
-> the sandbox user's current SID is absent -
Check inheritance:
(Get-Acl "C:\MiriGDKPv2\apps\api").AreAccessRulesProtected -> False
(Get-Acl "C:\MiriGDKPv2\apps\api\app").AreAccessRulesProtected -> FalseSo inheritance is not blocked, CodexSandboxUsers has (OI)(CI)(M) on both directories, but the sandbox user's own SID is not propagated to the descendant directories.
-
Confirm the fix:
icacls "C:\MiriGDKPv2\apps\api\app" /grant "*S-1-5-21-1747488710-827246756-3187947173-1006:(OI)(CI)(M)" /t /c /q
-> 212 files processed, 0 failed. Writes now succeed. But the fix is lost when the sandbox SID changes again.
What is the expected behavior?
When the sandbox user's SID changes, the elevated sandbox setup should either:
(a) recursively repair ACLs on all existing workspace descendants under the write roots, not just at the top level, OR
(b) fail loudly at startup with a clear, actionable error, telling the user what went wrong and how to fix it, OR
(c) automatically elevate and repair ACLs when it detects that the current sandbox user cannot write to a path it is expected to own.
Currently none of these happens. Codex silently loses the ability to edit parts of the workspace, and the only remedy is a manual icacls command that has to be repeated after every sandbox SID change.
Expected minimal behavior: if the sandbox detects it cannot write to a path under a configured write root, it should not proceed with a patch operation that will only fail with Access is denied. It should report the problem before the user invests effort in a task.
Additional information
Diagnostics from a real case
- Codex App version: 26.908.40834 (Windows)
- Platform: Windows 10 (10.0.19045.0 x64)
- Subscription: ChatGPT Pro
- Sandbox user (whoami): desktop-583kd57\codexsandboxoffline
- Sandbox user current SID: S-1-5-21-1747488710-827246756-3187947173-1006
Failure boundary
- Workspace root: C:\MiriGDKPv2
- Writes succeed: C:\MiriGDKPv2, C:\MiriGDKPv2\apps, C:\MiriGDKPv2\apps\api, C:\MiriGDKPv2\apps\web\src
- Writes fail: C:\MiriGDKPv2\apps\api\app, C:\MiriGDKPv2\apps\api\app\mirigdkp_api, and all their descendants
The boundary matches exactly where the sandbox user's current SID is absent from the ACL, even though the parent directory has inheritable ACEs that should have propagated down.
ACL evidence
icacls "C:\MiriGDKPv2\apps\api" shows (abbreviated):
DESKTOP-583KD57\CodexSandboxUsers:(OI)(CI)(M)
S-1-5-21-1747488710-...-1006:(I)(OI)(CI)(M) <- current sandbox SID, present here
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
...
icacls "C:\MiriGDKPv2\apps\api\app" shows the same set EXCEPT the sandbox user's current SID S-1-5-21-1747488710-...-1006 is absent.
Get-Acl confirms: AreAccessRulesProtected = False on both paths (inheritance is not blocked).
What did NOT help
- Reboot: did not repair the ACLs, the failure persisted across reboot.
- Attempting to write via Copy-Item instead of Set-Content: same error (CopyFileInfoItemUnauthorizedAccessError).
- fsutil reparsepoint query on the target file: "The file or directory is not a reparse point." (Confirms the apply_patch error message is misleading.)
What DID work
Running an elevated PowerShell and executing:
icacls "C:\MiriGDKPv2\apps\api\app" /grant "*S-1-5-21-1747488710-827246756-3187947173-1006:(OI)(CI)(M)" /t /c /q
Result: "Successfully processed 212 files; Failed processing 0 files." Writes restored until the next sandbox SID change.
Related issues
- #31888 (Windows: workspace-write sandbox blocks apply_patch with EPERM on %USERPROFILE%) — different scope: that's about writes outside the workspace; this is about writes inside the workspace, in existing descendants.
- #15165 (Windows elevated sandbox does not recursively grant usable ACLs to existing workspace files) — likely related root cause but different symptom set.
- #28943 (Fix Windows sandbox runtime ACL refresh) — fixed runtime binaries, not workspace descendants.
Impact
This breaks Codex on any Windows project with an established file tree. For a user who has been working in the same repository for weeks, the sandbox silently loses write access to most of the codebase. The user has to manually fix ACLs after every sandbox re-initialization, which they may not realize until Codex fails mid-task.
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 by reproducing the Windows ACL boundary with the listed PowerShell Set-Content, Get-Acl, and icacls commands, then trace the sandbox initialization and workspace ACL refresh behavior related to issues #15165 and #28943. Done means existing workspace descendants remain writable after a sandbox SID change, or startup reports an actionable failure before edits are attempted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- authorization, operating-systems, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100