Skip to content

Windows sandbox applies DENY ACLs to .git directories in writable_roots, breaking git commits #18918

Open

Description

@whyrv

What version of Codex CLI is running?

0.122.0

What subscription do you have?

PRO

Which model were you using?

gpt-5.4

What platform is your computer?

Windows 11 PRO

What terminal emulator and version are you using (if applicable)?

Gitbash/Powershell

What issue are you seeing?

Summary

After updating to the version released ~2026-04-20, Codex applies DENY ACEs to .git directories inside any path listed
in writable_roots, permanently breaking git commit (and any operation requiring .git/index.lock) for the sandboxed
process.

Root Cause

PR #18443 changed sandbox ACL setup to expand USERPROFILE into its direct children rather than granting the root. For
users whose repos live under a USERPROFILE child (e.g. C:\Users\me\OneDrive...), those repos are now in scope for
sandbox ACL grants. The sandbox applies DENY ACEs to the repo's .git directory — presumably to protect git history —
but those DENY ACEs are not cleaned up and persist after Codex exits, reapplied on every startup.

Observed Behavior

fatal: Unable to create '.../.git/index.lock': Permission denied

icacls .git shows explicit DENY ACEs for the sandbox SID:

.git S-1-5-21--:(DENY)(W,D,Rc,DC)
S-1-5-21--:(OI)(CI)(IO)(DENY)(W,D,Rc,GW,DC)

  • The DENY SID is the Codex sandbox identity (different domain from the local machine SID)
  • Removing the ACEs manually with icacls /remove:d works temporarily
  • Codex reapplies the DENY ACEs on next startup
  • The user's own account (vasan) retains full control and is unaffected — only the sandboxed process is blocked

Environment

Expected Behavior

.git directories inside writable_roots should be excluded from DENY ACE grants, consistent with how .ssh is excluded.
Git operations must work from within the sandbox.

Suggested Fix

In codex-windows-sandbox, add .git to the same exclusion list used for .ssh, .tsh, .brev. Apply the same pattern PR
#18493 uses for SSH config scanning — just statically exclude .git at any depth within a writable root, since the
sandbox has no legitimate reason to DENY-lock version control internals.

// alongside .ssh, .tsh, .brev exclusions:
".git",

What steps can reproduce the bug?

create .git under onedrive and have codex commit to it -- was working flawlessly till this upgrade.

What is the expected behavior?

"• I found the root cause: ACL on .git has an explicit DENY write entry for the Codex sandbox SID, so this
session cannot create index.lock (staging/commit blocked). I’ll try removing that deny ACE and then
finish commit/issue closeout." -- per codex itself

Additional information

No response

Activity

  1. added
    CLIIssues related to the Codex CLI
    windows-osIssues related to Codex on Windows systems
    sandboxIssues related to permissions or sandboxing
    on Apr 22, 2026
  2. viyatb-oai commented on Apr 22, 2026

    @viyatb-oai
    Contributor

    @whyrv this made windows sandbox consistent with behavior on macos and linux. in workspace-write sandbox mode, writes to .git are not allowed.

  3. whyrv commented on Apr 22, 2026

    @whyrv
    Author

    What is the workaround to restore old behavior: sandbox = "unelevated" doesn't seem to help either. The original behavior was working for months until this breaking change.

  4. ywkuno commented on Apr 22, 2026

    @ywkuno

    same issue here.

  5. paltenburg commented on Apr 22, 2026

    @paltenburg

    Additional Windows desktop repro details from my setup, in case this helps narrow it down.

    Environment:

    • Codex desktop app on Windows
    • repo at D:\Develop (so not under C:\Users\... / not under OneDrive)
    • sandbox_mode = "workspace-write"
    • [windows] sandbox = "elevated"

    What I observed before switching to full access:

    1. The visible Codex terminal and the autonomous backend tools were not running with the same effective identity.

      • Visible Codex terminal: whoami -> popke-dell-pc\palte
      • Autonomous backend tool path: whoami -> popke-dell-pc\codexsandboxonline
    2. In that state, the visible Codex terminal could write under .git, but the autonomous backend tool path could not.

      • Visible terminal succeeded with:
        • New-Item -Path D:\Develop\.git\index.lock -ItemType File -Force
        • Remove-Item D:\Develop\.git\index.lock -Force
      • Backend tool failed on a plain write under .git with:
        • Set-Content D:\Develop\.git\tool-check.tmp ok
        • error: Access to the path 'D:\Develop\.git\tool-check.tmp' is denied.
    3. Rebooting Windows and fully reinstalling Codex (including a clean install test) did not change that behavior.

    4. Switching Codex to danger-full-access immediately changed the backend tool behavior:

      • backend tool whoami became popke-dell-pc\palte
      • backend tool could then write under .git
      • after that, autonomous Git writes/commits started working again

    So there seem to be two useful data points here:

    • This reproduces on a repo outside C:\Users\..., at least in the desktop app.
    • In workspace-write, there is a Windows desktop identity split where the visible terminal can access .git, but autonomous backend tool execution still runs as the sandbox user and cannot.

    Workaround on my machine:

    • sandbox_mode = "danger-full-access"

    That is the only setting that restored autonomous Git writes for me.

  6. rentanything-nb commented on Apr 22, 2026

    @rentanything-nb

    @paltenburg , danger-full-access is exactly that... CODEX now has unrestricted access to do anything on your system. @viyatb-oai , I'll say the same thing I said in the other thread: Confirming that a change which made the product unusable is not an acceptable response to a bug report

  7. whyrv commented on Apr 23, 2026

    @whyrv
    Author

    sandbox_mode = "danger-full-access" works for me. So the fix from open-ai is to make the sandbox less secure by the user to go back to a working state,

  8. RoboLagoon commented on Apr 25, 2026

    @RoboLagoon

    They use LLM to develop a feature, that development breaks something that worked before introducing a new set of bugs. They fix them and introduce again a new set of bugs. Their process repeats and we see thousands of bugs reported in this repo, claude code etc. at the same time. The whole process is a joke. Devs do much better job than those modern AI agents everyone is worshipping so much. I have never seen so many issues in the apps developed by humans.

  9. whyrv commented on Apr 25, 2026

    @whyrv
    Author

    This particular issue works well with Claude Code, Kimi-cli, etc. So, it is specific to Codex’s over-protection and requires the user to keep the backdoor unlocked in this scenario.

  10. flumignano commented on Jun 18, 2026

    @flumignano

    This is still happening to me.

  11. h2cone commented on Jun 23, 2026

    @h2cone

    I’m seeing the same thing on Windows in Codex app.

    The UI says Full access, and Codex can edit normal files, but git add fails with:

    fatal: Unable to create '/.git/index.lock': Permission denied

    There is no existing index.lock. The .git ACL has explicit Deny entries for Write/Delete, so this looks like the same DENY ACL issue.

    The confusing part is that Full access is selected, but .git still isn’t writable.

  12. olinkluzz1v commented on Jul 13, 2026

    @olinkluzz1v

    I am experiencing what appears to be the same underlying bug in Codex Desktop on Windows 11, with two additional details: the repository is outside USERPROFILE, and the failure occurs in a linked Git worktree.

    Sanitized setup

    • Codex Desktop on Windows 11
    • Managed workspace-write sandbox
    • A normal Git repository under a dedicated development directory
    • Implementation performed in a linked worktree
    • The worktree’s .git file resolves to the main repository’s .git/worktrees/<worktree> directory

    Observed behavior

    1. Codex can modify ordinary source files.

    2. Git operations from the Codex sandbox fail when writing metadata:

      fatal: Unable to create '.../.git/worktrees//index.lock': Permission denied

    3. ACL inspection shows explicit DENY entries on .git or the resolved linked-worktree Git directory for sandbox-created identities.

    4. The same git add and git commit commands succeed immediately in regular, non-administrator PowerShell.

    5. Explicitly allowing the repository and .git paths in the Codex workspace configuration does not overcome the Windows ACL denial.

    6. The problem recurs across Codex tasks and restarts.

    7. A remote push later succeeded, but updating the local remote-tracking ref failed because its lock file could not be created under .git.

    This forces Codex to ask the user to stage and commit changes outside the app.

    Expected behavior

    • Authorized repositories should permit Git metadata writes required for staging, commits, and local ref updates.
    • Linked worktrees should authorize the resolved .git/worktrees/<worktree> directory.
    • Sandbox ACL entries should not persist or accumulate across sessions.

    The current workaround is running Git mutations in ordinary PowerShell. Administrator privileges are not required.

  13. brefledev commented on Sep 2, 2026

    @brefledev

    Reproduced in the ChatGPT desktop app on Windows 11.

    Environment:

    • Desktop package: OpenAI.Codex_26.831.1445.0
    • App file version: 152.0.7977.64
    • Bundled Codex CLI: 0.152.0
    • Windows sandbox: elevated

    Codex could edit ordinary workspace files, but git add failed with:

    fatal: Unable to create '<repo>/.git/index.lock': Permission denied
    

    icacls showed explicit sandbox-user DENY entries on .git, inherited by .git/index:

    (DENY)(W,D,Rc,DC)
    (OI)(CI)(IO)(DENY)(W,D,Rc,GW,DC)
    

    Removing the stale DENY entries restored Git access. A later ChatGPT desktop (Codex) task created a fresh entry under a new sandbox SID, and the failure returned.

    The cleanup is temporary. The elevated Windows sandbox reapplies the .git denial across desktop tasks.

    This may share the ACL-projection defect documented in #31265: a requested read denial produced write-denying ACL rights (W,D,Rc,DC). Those same rights appear on .git here.

  14. Sunchic70 commented on Sep 4, 2026

    @Sunchic70

    Additional linked-worktree evidence from Windows native Codex: scoped request_permissions grants were accepted, but Git metadata operations still failed.

    I understand that .git is protected in workspace-write by default; this report concerns the supported explicit-grant path, not a request to disable that protection.

    Environment: Windows 11 x64 (10.0.26200.0), native PowerShell, Git 2.55.0.windows.3. The available Doctor report identifies Codex CLI 0.153.0; the exact desktop build at failure was not independently captured. Effective agent execution was managed workspace-write.

    Observed sequence:

    1. An authorized rebase was paused in a linked worktree. Its Git metadata resolves under the main repository's .git/worktrees/<worktree>, with shared packed refs in the common .git directory.
    2. A session-level write request for packed-refs, packed-refs.lock, and the linked-worktree metadata directory was accepted. Normal git -c rebase.updateRefs=false rebase --continue still exited 1.
    3. A second session-level write request for the common .git directory was accepted. Continuation still failed with these errors (paths redacted):
      Unable to create '<common-git-dir>/packed-refs.lock': Permission denied
      could not remove CHERRY_PICK_HEAD
      
    4. Read-only restricted-token inspection found a restricted SID matching explicit/inherited write/delete DENY entries on the affected metadata. Subsequent read-only checks found no packed-refs.lock, linked-worktree index.lock, or active Git process.

    The original branch and backup refs are preserved; the worktree/index are clean, but the rebase remains incomplete after one of five commits. No manual ACL removal, ownership reset, security disabling, or alternate execution identity was used during this recovery attempt.

    This is an observed managed-grant/effective-access mismatch, not a confirmed implementation root cause or a clean-room reproduction. Could the team clarify whether request_permissions should authorize this common-Git/linked-worktree metadata, and investigate why grants were accepted without enabling the required writes? A narrowly scoped supported recovery path that preserves sandbox protections and the unfinished rebase would help.

  15. keak3098-collab commented on Sep 6, 2026

    @keak3098-collab

    Additional observed case in Windows Codex Desktop: a turn-scoped write grant was accepted, but staging in an existing checkout still failed.

    Feedback was submitted through the app. Feedback ID: 01a06953-9795-7f61-a557-798a4188b009.

    Environment

    • Native Windows desktop app; bundled CLI reports 0.153.4. The desktop app version was not separately captured.
    • OS API reports Windows build 10.0.26200.0.
    • Windows sandbox configuration: elevated.
    • Effective execution: managed workspace-write, with granular approvals allowing request_permissions and MCP elicitations, while shell escalation, rules and skill-script approvals are disabled.

    Observed sequence

    1. The app was closed and reopened after earlier permission failures.
    2. Read-only checks found no existing .git/index.lock and explicit deny entries on the checkout's .git.
    3. A fresh request_permissions request asked for write access only to the existing checkout and its .git directory, without network or Full access. The tool returned a turn-scoped write grant.
    4. In that turn, one git add -- attempt targeting six validated project files failed with exit code 128:
      Unable to create '.../.git/index.lock': Permission denied
      
    5. The attempt was stopped. No commit, push, deployment, ACL changes, sandbox disabling, repository relocation, or alternate execution identity was used.

    This is an observed grant/effective-access mismatch, not a confirmed implementation root cause or a clean-room reproduction. Unlike the linked-worktree rebase case described above, this attempt was ordinary staging in the existing checkout.

    I understand that .git is protected by default in workspace-write. The question is about the supported explicit-grant path: should an accepted write grant for this directory enable the authorized operation? If the grant cannot override this protection, it would help for the permission result to report that limitation accurately instead of appearing to authorize an operation that still cannot run.

    A supported, narrowly scoped correction that preserves sandbox protections would help. The local source changes remain preserved.

    No customer data, passwords, project source, full local paths, chat history, diagnostic logs, or browser logs are attached to this comment.

  16. keak3098-collab commented on Sep 7, 2026

    @keak3098-collab

    Follow-up to my earlier report in this issue: a later read-only diagnostic separated the Git ownership check from the remaining explicit-grant/write failure.

    Observed on 7 September 2026, with the command's execution working directory set to the original checkout:

    • Git status succeeded under both the managed Offline and Online execution identities. The runner supplied inherited command-scoped Git configuration; no agent-added trust exception, ownership change, or ACL modification was made.
    • The next ordinary staging operation, limited to two existing UI files, failed with exit 128: "Unable to create '.../.git/index.lock': Permission denied".
    • A fresh turn-scoped write request for that exact protected .git directory returned granted. One staging retry under that grant failed with the same error.
    • There was no pre-existing index.lock. The conditional commit did not run, and this diagnostic did not push, deploy, replace source, relocate the checkout, or change security settings. Existing work remains preserved.

    On 8 September, read-only inspection again found no index.lock and confirmed the local changes remain intact. We have not repeated grants or write probes without evidence of a relevant platform change.

    This updates the earlier ownership diagnosis: ownership validation now passes for this original-working-directory invocation, but the protected-Git write operation still fails. The mere presence of Deny ACL entries, or an access result from the Offline token, does not establish the effective access decision for the Online token.

    Could the team investigate whether the accepted exact-path write grant is applied to the actual managed Online execution token, including any restricting SIDs and protected-path policy? A supported, narrowly scoped correction that preserves sandbox protections is needed. If this grant cannot authorize Git metadata writes, please clarify the supported recovery path and why the grant result reports success.

    This remains an observed grant/effective-access mismatch, not a confirmed implementation root cause. No customer data, credentials, source code, full local paths, raw logs, or chat history are attached.

  17. gotisgate commented on Sep 16, 2026

    @gotisgate

    I can reproduce this in Codex Desktop on Windows. I believe the following adds a different kind of evidence to the existing Desktop reproductions: I captured the DACL rewrite itself with Process Monitor and independently bracketed it against the exact .git ACL transition.

    In particular, this is not only a before/after observation of DENY ACEs appearing after Codex activity. The codex.exe SetSecurityFile event occurs inside the independently observed transition from zero matching DENY ACEs to two matching DENY ACEs.
    The failure is:

    fatal: Unable to create '.git/index.lock': Permission denied

    The affected .git directory contains two explicit non-inherited DENY ACEs for a SID that is also present in the restricted SID set of the Codex execution token.

    I performed a controlled ACL experiment:

    1. With the DENY ACEs present, writes under .git fail with Win32 error 5.
    2. From an elevated control process, I removed only the two matching explicit DENY ACEs, leaving unrelated ACEs, inheritance, owner, group, and SACL unchanged.
    3. Immediately afterward, writes to the original .git succeeded.
    4. While Codex remained active, the same two DENY ACEs were later recreated and writes failed again.

    I then captured the recreation with Process Monitor while independently polling the .git ACL.

    For one captured transition:

    • Last observation with matching DENY ACE count = 0: 17:19:14.8881435
    • codex.exe performed SetSecurityFile on the repository root .git: 17:19:14.8976038
    • First observation with matching DENY ACE count = 2: 17:19:14.9194420

    The SetSecurityFile event therefore falls directly inside the observed 0 → 2 transition window.

    Process Monitor attributes the operation to codex.exe, with SUCCESS and DACL as the security information being changed. The captured stack reaches:

    codex.exe → SetNamedSecurityInfoW → SetKernelObjectSecurity → ZwSetSecurityObject

    A direct before/after security-descriptor comparison confirms that the two matching DENY ACEs were added across this transition.

    I also tested lifecycle boundaries. After removing the DENY ACEs with all Codex/OpenAI processes absent, they remained absent. A true Codex cold start likewise left them absent for the observation period, including restoration of the existing workspace/session. The 0 → 2 transition was observed later while Codex was actively processing a task.

    This appears to narrow the problem beyond persistent stale ACLs: in my reproduction, codex.exe itself actively rewrites the .git DACL during an active session and recreates the DENY entries that prevent its restricted execution context from creating .git/index.lock.

    I can provide a minimized Procmon trace / ACL before-and-after data if that would be useful for maintainers.

  18. raled573343 commented on Sep 26, 2026

    @raled573343

    We found a practical workaround for the Git-specific part of this on Windows: run all Git commands in host context and keep code/tests inside the sandbox. Details posted in #37965 (comment)

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

    bugSomething 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