Symlinks in `permissions.*.filesystem` dropped instead of passed-through to bwrap with real path

Open
#34,530 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
55/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
linux, rust

Research direction

Reproduce the issue with the shown permissions.codex_sandbox.filesystem configuration on Linux and compare literal rules with :minimal. Trace filesystem permission canonicalization into the Bubblewrap mount construction. Done means canonicalized symlink paths such as /bin remain available in the sandbox, with a regression test for the reproduced configuration.

Written by the indexing model from the issue text.

Description

bug CLI config sandbox
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.
Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.