Symlinks in `permissions.*.filesystem` dropped instead of passed-through to bwrap with real path
Open 💬 1 comment Opened Jul 21, 2026 by aowenson-imm
What version of Codex CLI is running?
0.144.5
What subscription do you have?
ChatGPT Edu
Which model were you using?
gpt-5.6-terra
What platform is your computer?
Linux 6.8.0-107-generic x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
Bash
What issue are you seeing?
If a path in my [permissions.*.filesystem] is a symlink, then after Codex canonicalizes it to pass real path to bwrap, it discard the symlink. So anything inside Codex session using the symlink instead of real path, breaks. Even if I have both the symlink and real path in config.
Baseline: this works:
$ cat ~/.codex/config.toml
approval_policy = "on-request"
default_permissions = "codex_sandbox"
[permissions.codex_sandbox.filesystem]
:minimal "read"
But if I manually enumerate the minimal paths:
$ cat ~/.codex/config.toml
approval_policy = "on-request"
default_permissions = "codex_sandbox"
[permissions.codex_sandbox.filesystem]
"/bin" = "read"
"/sbin" = "read"
"/lib" = "read"
"/lib64" = "read"
"/etc" = "read"
"/usr" = "read"
Then Codex gets this error when trying to run anything:
Failed to execvp /bin/sh: No such file or directory (os error 2)
A separate analysis with working Codex thinks problem is:
For literal rules, Codex canonicalizes the path before constructing the Bubblewrap mounts. On Ubuntu 22:
/bin -> /usr/bin
/sbin -> /usr/sbin
/lib -> /usr/lib
/lib64 -> /usr/lib64
So then /bin is dropped.
What steps can reproduce the bug?
Set your config to:
$ cat ~/.codex/config.toml
approval_policy = "on-request"
default_permissions = "codex_sandbox"
[permissions.codex_sandbox.filesystem]
"/bin" = "read"
"/sbin" = "read"
"/lib" = "read"
"/lib64" = "read"
"/etc" = "read"
"/usr" = "read"
Then ask Codex to run any Linux command.
What is the expected behavior?
Don't drop paths that were canonicalized, match what :minimal does:
:minimal takes a different code path: Codex injects /bin, /sbin, /usr, /etc, /lib, and /lib64 as raw Bubblewrap mount targets, preserving /bin in the namespace. That is why it works.
1 Comment
I have same problem, but on macOS.
I have a dotfiles repository at
~/dotfilesand creating symlink to~/from~/dotfiles/home/.and i have a config like:
but symlinks will be resolved to actual path when creating sandbox:
so
cat ~/.gitconfigfails because it can't read symlink at~/.gitconfig: