codex app-server tool commands run in read-only sandbox despite --dangerously-bypass-approvals-and-sandbox

Open 💬 2 comments Opened Mar 9, 2026 by kinoh

What version of Codex CLI is running?

codex-cli 0.112.0

What subscription do you have?

Plus

Which model were you using?

unknown (invoked through codex app-server)

What platform is your computer?

Ubuntu on WSL2 (Linux 6.8.0-101-generic x86_64 x86_64)

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

_No response_

What issue are you seeing?

When codex app-server is started with --dangerously-bypass-approvals-and-sandbox, tool-executed child processes still run inside codex-linux-sandbox with a read-only sandbox policy.

As a result, write operations fail with Permission denied, even though the app-server itself was launched in bypass mode.

Observed failures from the app-server path:

touch .git/_perm_check && rm .git/_perm_check
touch: cannot touch '.git/_perm_check': Permission denied
touch /tmp/perm_check && rm /tmp/perm_check
touch: cannot touch '/tmp/perm_check': Permission denied
git pull
error: cannot open '.git/FETCH_HEAD': Permission denied

From inside the tool child process launched by app-server:

/proc/self/status:NoNewPrivs:    1
/proc/self/status:Seccomp:       2
/proc/self/status:Seccomp_filters:       1
/proc/<parent>/status:NoNewPrivs:        0
/proc/<parent>/status:Seccomp:   0
/proc/<parent>/status:Seccomp_filters:   0

On the same machine and same repository, both of the following work correctly:

  • direct root shell on the host
  • codex exec --dangerously-bypass-approvals-and-sandbox

strace shows that the app-server path launches tool commands through a read-only sandbox:

execve(".../codex/codex", ["codex-linux-sandbox", "--sandbox-policy-cwd", "/var/lib/cards/workspace", "--sandbox-policy", "{\"type\":\"read-only\"}", "--", "/bin/bash", "-c", ...], ...)
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0
seccomp(SECCOMP_SET_MODE_FILTER, 0, ...) = 0
execve("/bin/bash", ["/bin/bash", "-c", "touch /tmp/perm_check && rm /tmp/perm_check"], ...)

This makes codex app-server ignore --dangerously-bypass-approvals-and-sandbox for tool command execution.

Additional confirmation:

  • Reproduced on both @openai/codex 0.111.0 and 0.112.0
  • Reproduces only via codex app-server
  • Does not reproduce via codex exec --dangerously-bypass-approvals-and-sandbox on the same host and same repository

Direct evidence from strace on the app-server worker:

execve(".../codex/codex", ["codex-linux-sandbox", "--sandbox-policy-cwd", "/var/lib/cards/workspace", "--sandbox-policy", "{\"type\":\"read-only\"}", "--", "/bin/bash", "-c", ...], ...)
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0
seccomp(SECCOMP_SET_MODE_FILTER, 0, ...) = 0
execve("/bin/bash", ["/bin/bash", "-c", "touch /tmp/perm_check && rm /tmp/perm_check"], ...)

This shows that app-server is explicitly launching tool commands through codex-linux-sandbox with {"type":"read-only"}, even though the app-server itself was started with --dangerously-bypass-approvals-and-sandbox.

What steps can reproduce the bug?

  1. Start app-server in bypass mode:
codex --dangerously-bypass-approvals-and-sandbox app-server
  1. Connect any app-server client and send a prompt that triggers tool execution in a writable git repository, for example:
Run these commands and report raw stdout/stderr:
touch .git/_perm_check && rm .git/_perm_check
touch /tmp/perm_check && rm /tmp/perm_check
git pull
sh -lc 'grep -E "^(NoNewPrivs|Seccomp|Seccomp_filters):" /proc/self/status /proc/$PPID/status'
  1. Observe that writes fail with Permission denied, and the tool child process shows:
NoNewPrivs: 1
Seccomp: 2
Seccomp_filters: 1
  1. On the same machine, run the equivalent direct CLI path:
codex exec --dangerously-bypass-approvals-and-sandbox --json -C /path/to/writable/git/repo \
'Run these commands and report raw stdout/stderr:
touch .git/_perm_check_direct && rm .git/_perm_check_direct
touch /tmp/perm_check_direct && rm /tmp/perm_check_direct
git pull
sh -lc '"'"'grep -E "^(NoNewPrivs|Seccomp|Seccomp_filters):" /proc/self/status /proc/$PPID/status'"'"''
  1. Observe that in codex exec:
  • writes succeed
  • git pull succeeds
  • the child process shows:
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
  1. Optional confirmation with strace attached to the app-server worker:
sudo strace -ff -p <app_server_worker_pid> -e trace=execve,clone,clone3,fork,vfork,prctl,seccomp -o /tmp/codex-appserver.trace

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗