deny-read permission profile silently ineffective on native Windows (ACL state empty) — 0.142.5
Open 💬 2 comments Opened Jul 6, 2026 by yoshitakafumoto-xyn
Summary
On native Windows, a permission profile with a valid deny filesystem rule does not
apply read denial. write denial works; read denial does not. Sandboxed commands can
still read files that a deny rule should block (e.g. ~/.codex/config.toml).
Environment
- codex-cli 0.142.5 (latest stable)
- Windows 11 Home, build 26200
- Native Windows sandbox,
[windows] sandbox = "elevated"(elevated backend set up)
Config (corrected to documented syntax)
default_permissions = "review-egress"
[permissions.review-egress.filesystem]
"~/.ssh" = "deny"
[permissions.review-egress.filesystem.":workspace_roots"]
"." = "read"
Steps to reproduce
- Apply the config above with the elevated Windows sandbox backend.
- Run a sandboxed command that reads an absolute path under a
denyrule. - Observed: the file is read successfully;
deny_read_acl_state.jsonremains empty ({"principals": {}}). - Expected: read is blocked by policy (parity with write-deny, and with macOS/Linux).
Notes
- write-deny behaves correctly; only read-deny is ineffective.
- Non-elevated returns an "elevated backend required" error (i.e. the rule is now
recognized, unlike undocumented keys which were silently ignored).
- Sandbox log shows "read-acl-only mode: applying read ACLs" completing in ~1ms with no deny ACEs applied.
- Possibly related: #28566, #30758.
Impact
Any workflow relying on read-deny for secret isolation on native Windows is silently
unprotected, with no error surfaced when the elevated backend is present.
2 Comments
@yoshitakafumoto-xyn Still present on
codex-cli 0.147.0-alpha.6(npmalpha, published 2026-08-03), five minorversions after the 0.142.5 reported here. Below is some detail from inspecting the file permissions
afterwards, plus one behavior that may point at the underlying cause.
Environment: Windows 11 Pro 10.0.26200,
[windows] sandbox = "elevated", elevated backendinstalled.
The exact path rule and the glob rule fail in different ways
For the exact path rule, Codex does create a deny entry. The problem is what that entry denies:
The letters
(W,D,Rc,DC)are write, delete, read control, and delete child. There is no readpermission in that list, so reading the file is not affected.
For the glob rule, no deny entry is created at all. The file's permissions are left untouched.
I used
*.envrather than**/*.envon purpose. The code warns that**patterns are notsupported outside macOS and suggests writing explicit patterns such as
*.envinstead. Thatsuggested form behaves the same way.
**/*.envgave identical results.The deny rule appears to block writing instead of reading
Same file, same profile:
Reading the file works, which the rule was supposed to prevent. Writing to the file is blocked,
which the rule never asked for. The third command confirms that writing to other files in the same
workspace still works, so the block is specific to the file covered by the deny rule.
This matches the permissions shown above. The deny entry blocks the access that was not requested,
and allows the access that was.
That raises something worth checking. There are several open reports of deny-read entries breaking
writes: #18918 (deny entries on
.gitbreaking commits), #31229 (apply_patchcan add files butcannot update them), and #36087. If a deny-read rule produces a write-deny entry, those reports and
this one may be the same problem seen from opposite sides. I have not confirmed that, and someone
familiar with how these entries are built could rule it in or out quickly.
The log and the state file disagree
Meanwhile
.sandbox/deny_read_acl_state.jsonstill contains{"principals": {}}, which matcheswhat you reported. There is no log line at all for the file matched by the glob, which fits with no
entry being created for it.
@viyatb-oai you added Windows deny-read in #18202 and made
denycanonical in #23493, so you maybe the best person to say whether the write-deny entry above is the intended construction or a bug
in how the entry is built. This reproduces reliably here and I am happy to run further tests.
Reproduced on codex-cli 0.145.0 — Windows 11 Pro build 26200, elevated sandbox backend in use.
Symptom matches this issue: custom permission profiles with read-deny rules are parsed and loaded (session records show
file_system: restricted, sandboxed commands run ascodexsandboxoffline), yet reads outside the workspace still succeed from PowerShell. The deny-read ACL state remains empty ({"principals": {}}) after runs.Configurations tested (all silently ineffective):
":root" = "deny",":minimal" = "read", workspace write)denyentries for three external directories*.mdIn all three cases, ordinary files under
C:\Users\Public\Documents, the user's Documents folder, and an external drive directory were fully readable from the sandboxed shell (exit code 0, contents returned), whilewhoamiconfirmed the restricted identity was active.Control observations:
Access is denied, exit code 1). So OS-level enforcement works when ACLs are actually present — the missing piece appears to be the config→ACL projection step.Restricted read-only access requires the elevated Windows sandbox backend, which is good. The silent-ineffective behavior above occurs with elevated in use.One additional note that may help triage: child sessions spawned from a Codex Desktop task inherit
CODEX_PERMISSION_PROFILE=:danger-full-accessfrom the parent environment, which overrides the config profile and can mask (or be mistaken for) this bug. The ACL-projection failure reproduces independently after scrubbing that variable from the environment.Happy to provide fuller transcripts if useful.