## Summary - always pass `--unshare-user` in the Linux bubblewrap argv builders - stop relying on bubblewrap's auto-userns behavior, which is skipped for `uid 0` - update argv expectations in tests and document the explicit user namespace behavior The installed Codex binary reproduced the same issue with: - `codex -c features.use_linux_sandbox_bwrap=true sandbox linux -- true` - `bwrap: Creating new namespace failed: Operation not permitted` This happens because Codex asked bubblewrap for mount/pid/network namespaces without explicitly asking for a user namespace. In a root-inside-container environment without ambient `CAP_SYS_ADMIN`, that fails. Adding `--unshare-user` makes bubblewrap create the user namespace first and then the remaining namespaces succeed.
2.2 KiB
2.2 KiB
codex-linux-sandbox
This crate is responsible for producing:
- a
codex-linux-sandboxstandalone executable for Linux that is bundled with the Node.js version of the Codex CLI - a lib crate that exposes the business logic of the executable as
run_main()so that- the
codex-execCLI can check if its arg0 iscodex-linux-sandboxand, if so, execute as if it werecodex-linux-sandbox - this should also be true of the
codexmultitool CLI
- the
On Linux, the bubblewrap pipeline uses the vendored bubblewrap path compiled into this binary.
Current Behavior
- Legacy Landlock + mount protections remain available as the legacy pipeline.
- The bubblewrap pipeline is standardized on the vendored path.
- During rollout, the bubblewrap pipeline is gated by the temporary feature
flag
use_linux_sandbox_bwrap(CLI-calias forfeatures.use_linux_sandbox_bwrap; legacy remains default when off). - When enabled, the bubblewrap pipeline applies
PR_SET_NO_NEW_PRIVSand a seccomp network filter in-process. - When enabled, the filesystem is read-only by default via
--ro-bind / /. - When enabled, writable roots are layered with
--bind <root> <root>. - When enabled, protected subpaths under writable roots (for example
.git, resolvedgitdir:, and.codex) are re-applied as read-only via--ro-bind. - When enabled, symlink-in-path and non-existent protected paths inside
writable roots are blocked by mounting
/dev/nullon the symlink or first missing component. - When enabled, the helper explicitly isolates the user namespace via
--unshare-userand the PID namespace via--unshare-pid. - When enabled and network is restricted without proxy routing, the helper also
isolates the network namespace via
--unshare-net. - In managed proxy mode, the helper uses
--unshare-netplus an internal TCP->UDS->TCP routing bridge so tool traffic reaches only configured proxy endpoints. - In managed proxy mode, after the bridge is live, seccomp blocks new AF_UNIX/socketpair creation for the user command.
- When enabled, it mounts a fresh
/procvia--proc /procby default, but you can skip this in restrictive container environments with--no-proc.
Notes
- The CLI surface still uses legacy names like
codex debug landlock.