Linux bubblewrap bootstrap fails for custom permission rules targeting regular or missing paths
What version of Codex CLI is running?
codex-cli 0.149.1
What platform are you using?
Linux x86_64 on a shared multi-user host.
What issue are you seeing?
Custom filesystem permission profiles can cause the Linux bubblewrap sandbox to
fail during app-server/TUI bootstrap, before AGENTS.md instructions load or a
model request begins.
Three related path shapes produced distinct failures:
- A writable rule targeting a regular file caused Codex to synthesize child
mount paths beneath that file:
``text``
bwrap: Can't mkdir parents for /home/user/.codex/config.toml/.git:
Not a directory
The sandbox helper then panicked while inspecting:
``text``
/home/user/.codex/config.toml/.codex
- A writable workspace-relative path that did not exist caused a bind-mount
failure:
``text``
bwrap: Can't bind mount /bindfile... on
/newroot/workspace/project/.agents:
No such file or directory
- An exact deny rule beneath a missing optional directory caused bubblewrap to
attempt to create the masking target beneath a read-only parent:
``text``
bwrap: Can't create file at
/workspace/another-project/.agents/.env:
Read-only file system
These failures also affect:
codex --strict-config doctor --json
because it exercises app-server/session bootstrap.
What steps can reproduce the bug?
Use a custom permission profile and test the following variants separately.
Variant A: regular file used as a writable root
default_permissions = "repro"
[permissions.repro]
[permissions.repro.filesystem]
":minimal" = "read"
"~/.codex/config.toml" = "write"
[permissions.repro.filesystem.":workspace_roots"]
"." = "write"
Start Codex or run:
codex --strict-config doctor --json
Variant B: missing optional writable path
In a workspace without a .agents directory:
default_permissions = "repro"
[permissions.repro]
[permissions.repro.filesystem]
":minimal" = "read"
[permissions.repro.filesystem.":workspace_roots"]
"." = "write"
".agents" = "write"
Start Codex.
Variant C: exact deny path beneath a missing directory
In a workspace without .agents:
default_permissions = "repro"
[permissions.repro]
[permissions.repro.filesystem]
":minimal" = "read"
[permissions.repro.filesystem.":workspace_roots"]
"." = "write"
".agents/.env" = "deny"
Start Codex, including through an app-server session containing multiple
workspace roots.
What is the expected behavior?
- A regular-file permission should be represented as a file mount rather than
treated as a directory root.
- Missing optional paths should be protected or made writable entirely inside
the mount namespace without requiring host-side targets to exist.
- A deny rule beneath a missing parent should not abort sandbox creation.
- If a permission shape cannot be represented safely, Codex should return a
clear configuration diagnostic rather than panic or fail session bootstrap.
Workaround
Using Codex's built-in :workspace permission profile avoids the failing custom
filesystem-rule expansion.
Related issues
- #39944 — denying
slash_tmp breaks Linux synthetic-mount bootstrap.
- #37318 — a missing
.git
target causes bubblewrap setup failure.
- #23601 — read-only failure
while creating .codex/tmp.
- #16088 — missing protected
paths are materialized during sandbox setup.
- #17079 — protected carveout
mount failure for symlink layouts.
- #33479 and
#37632 — related but distinct
recursive expansion of relative :workspace_roots rules.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Current
mainstill has code paths that line up with the first two reported shapes:create_filesystem_argsfiltersget_writable_roots_with_cwdto roots that already exist. That drops an explicit missing.agentswritable root before mount construction, so the narrower write rule cannot override protection inherited from the existing workspace root.append_metadata_path_masks_for_writable_rootunconditionally appends.git,.agents, and.codexchildren to each writable root. If the writable root is a regular file such asconfig.toml, those become impossibleconfig.toml/.git-style targets, matching variant A.The focused regression coverage seems to be: (1) an existing regular file as an explicit write root should return a configuration diagnostic or produce a file bind without metadata children; and (2) an explicit missing child write root under an existing workspace root should retain its override semantics without requiring a host-side target. Variant C likely needs its own ordering assertion around
append_unreadable_root_args, since missing paths are masked at their first nonexistent component.