GPU access for the Codex CLI Linux sandbox, implemented as a small
bubblewrap shim and a codex-gpu launcher.
This is an interim workaround for personal use. It is not an official OpenAI project, is not endorsed by the Codex team, and makes deliberate security trade-offs that are important to understand before using it.
GPU access has been a recurring Codex CLI sandbox limitation for some time. The original upstream request, Allow GPU access inside sandbox #3141, was opened in September 2025 and remains open. More recent reports describe the same broad problem in the current Linux sandbox implementations:
- workspace-write sandbox blocks GPU access
#19676 describes missing
/dev/nvidia*nodes in the bubblewrap namespace and also remains open. - linux-sandbox (bwrap) - GPU Access #23525 calls out device mounts and driver behavior; it was closed as a duplicate.
- GPU access blocked in the Linux sandbox on WSL2
#22469 covers the related
/dev/dxgcase and was also closed as a duplicate.
The obvious diagnosis is that Codex constructs a fresh /dev inside
bubblewrap and does not expose the host GPU device nodes. That is true, but our
investigation found that it is only the first blocker.
There are at least two independent layers involved:
- Codex uses bubblewrap's
--dev /dev, which replaces the visible device tree with a minimal one. Regular writable-root mounts use--bind, which carriesMS_NODEV; the NVIDIA device may appear as a path, but the kernel will not treat it as a usable device. GPU nodes require--dev-bindafter the fresh/devmount. - After bubblewrap creates the namespaces, Codex re-enters its Linux sandbox
helper and installs a restricted-network seccomp filter. CUDA's UVM FD
transport creates an abstract Unix
SOCK_SEQPACKETsocket and needs operations includingSO_PASSCREDandbind. The filter rejects those operations, sonvidia-smican work while real CUDA initialization still fails withCUDA_ERROR_OPERATING_SYSTEM(304).
This means upstream GPU support is a careful permission-design exercise for the Codex team, not just another mount flag. A robust design needs to decide which devices and platforms are supported, how GPU access is granted explicitly, which local IPC operations CUDA needs, how host-visible Unix sockets and inherited descriptors remain protected, how managed network proxies interact with the policy, and what additional attack surface GPU device handles introduce.
See exploration.md for the full source audit, experiments, failure traces, historical context, and validation results.
The package has two parts:
bin/codex-gpufinds the realcodex, prepends this package's private shim directory to itsPATH, and forwards every Codex command-line argument unchanged.shim/bwrapdelegates to the real bubblewrap after injecting--dev-bindentries for detected GPU devices.
For the narrowly recognized Codex inner-helper invocation, the shim also
changes the serialized permission profile from "network":"restricted" to
"network":"enabled". It does this only while bubblewrap's outer
--unshare-net remains present. The result is that CUDA's required socket
operations work while the sandbox still has a separate, loopback-only network
namespace with no outbound route.
This is intentionally an interim personal solution. Changing the inner profile causes Codex to skip its restricted seccomp filter as a whole; it is broader than allowing only the two CUDA operations observed in the trace. The filesystem, user, process, and outer network namespaces remain, but syscall isolation is weaker than in a normal restricted Codex sandbox.
- Linux
- Codex CLI installed and available as
codexonPATH - An NVIDIA GPU with a working host driver
nvidia-smifor the basic verification command- A usable
bubblewrapbinary, either installed on the system or bundled with Codex in a layout the shim recognizes
This project is currently tested on Arch Linux with bubblewrap 0.11.2, an NVIDIA GeForce RTX 5080, driver 610.43.03, and Codex CLI 0.146.0.
After cloning the repository, run the following from the directory containing
the bwrap-shim-codex checkout:
sudo cp -r ./bwrap-shim-codex /opt/Add the launcher's directory to PATH. For Bash or Zsh, add this line to the
appropriate shell configuration file, such as ~/.bashrc or ~/.zshrc:
export PATH="/opt/bwrap-shim-codex/bin:$PATH"Open a new terminal, or refresh the current shell:
exec "$SHELL" -lConfirm that the launcher is available:
command -v codex-gpu
codex-gpu --versionThen use codex-gpu anywhere you would normally use codex:
codex-gpu
codex-gpu -C /path/to/project
codex-gpu exec "run the GPU test suite"
codex-gpu sandbox -- nvidia-smi -Lcodex-gpu does not maintain a separate Codex CLI interface. It forwards all
options, subcommands, prompts, and trailing command arguments to the installed
codex executable.
Do not put /opt/bwrap-shim-codex/shim on your global PATH and do not
install its bwrap as the system bubblewrap. Only the bin directory is meant
to be globally visible. The launcher exposes the shim to its child Codex
process without affecting Flatpak, Steam, or other bubblewrap consumers.
The test suite checks argument preservation, safe passthrough, device binding, the permission-profile guards, real CUDA context creation and allocation, and retention of the outer network namespace:
./bwrap-shim-codex/test/test.shSome tests require a working NVIDIA GPU, nvidia-smi, Python 3, and permission
to create bubblewrap namespaces.
The shim prefers, in order:
BWRAP_SHIM_REAL, when explicitly set;- the first real
bwrapfound onPATH, excluding the shim itself; and - a bubblewrap binary in one of the legacy bundled Codex layouts recognized by the shim.
The bundled fallback prevents the shim from unnecessarily breaking Codex on
systems without a separately installed bubblewrap package. It is not a perfect
copy of Codex's evolving resource discovery: current Codex builds can also use
install-context and Bazel resource locations that this shim does not know
about. If neither a system bubblewrap nor a recognized bundled copy exists, the
shim exits with status 127 and an explanatory message. Installing your
distribution's bubblewrap package is the most predictable setup.
- GPU device access is additional privilege. Sandboxed code can consume GPU compute and memory, interact with the kernel driver through ioctls, and may affect other GPU workloads on the machine.
- The inner
network: enabledworkaround disables Codex's restricted seccomp filter, not only the socket operations used by CUDA. Bubblewrap's outer--unshare-netremains, so outbound IP connectivity is still unavailable, but visible Unix-domain sockets and other syscalls lose that seccomp layer. - Managed proxy networking (
--allow-network-for-proxy) is intentionally not handled by this workaround. - The shim depends on Codex's current Linux sandbox argument shape. A future Codex or bubblewrap release may require this project to be re-audited.
- Codex ignores a
bwraplocated below the current working directory. The/optinstallation avoids this in normal use, andcodex-gpurefuses to launch when it detects the problematic layout rather than silently running without GPU access. - This implementation is focused on native Linux NVIDIA/CUDA devices. It does
not currently expose the WSL2-specific
/dev/dxgpath. - Shell completions generated by
codex-gpu completionstill target the command namecodex, because the real Codex CLI intentionally uses that fixed name in its generated interface.
Use this only where these trade-offs are acceptable. It should not be treated as a production-quality sandbox permission design for untrusted workloads.
We are not accepting contributions at the moment. If you want to change, extend, or maintain this project, you are welcome to fork it and develop your own variant.
Licensed under the MIT License.