[FEATURE] GPU device passthrough in sandbox mode

Open 💬 7 comments Opened Dec 5, 2025 by benvanik

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Sandbox mode blocks GPU access because /dev/dri and /dev/kfd (etc) aren't passed through. This breaks Vulkan, ROCm/HIP, and CUDA workflows when the sandbox is enabled.

Step 1: Configure sandbox for filesystem protection

{
  "sandbox": { "enabled": true, "autoAllowBashIfSandboxed": true },
  "permissions": { "allow": ["Bash"] }
}

Step 2: Ask Claude to verify GPU access
Check if the GPU is available and run a simple PyTorch test

Step 3: Claude runs diagnostics:

# AMD GPU
rocm-smi --showid
hipconfig --version

# NVIDIA GPU
nvidia-smi

# Vulkan (any GPU)
vulkaninfo --summary

Step 4: Today, all fail - devices don't exist in sandbox:

$ rocm-smi --showid
No AMD GPUs found

$ vulkaninfo --summary
GPU0: llvmpipe (LLVM 20.1.8, 256 bits)    # CPU fallback only
      deviceType = PHYSICAL_DEVICE_TYPE_CPU

$ ls /dev/dri /dev/kfd
ls: cannot access '/dev/dri': No such file or directory
ls: cannot access '/dev/kfd': No such file or directory

Expected: GPU device nodes passed through, hardware detected.

Proposed Solution

Add sandbox.devices setting, e.g. for AMD:

{
  "sandbox": {
    "enabled": true,
    "devices": ["/dev/dri", "/dev/kfd"]
  }
}

Or for NVIDIA:

{
  "sandbox": {
    "enabled": true,
    "devices": ["/dev/dri", "/dev/nvidia0", "/dev/nvidiactl", "/dev/nvidia-uvm"]
  }
}

Claude Code's sandbox already uses https://github.com/containers/bubblewrap on Linux. Bwrap natively supports device passthrough via https://www.mankier.com/1/bwrap:

  --dev-bind-try SRC DEST   Bind mount host path SRC on DEST, allowing device access.
                            Ignores non-existent SRC (graceful on systems without GPUs).

So the setting above would add to the bwrap invocation:

  --dev-bind-try /dev/dri /dev/dri \
  --dev-bind-try /dev/kfd /dev/kfd

or

  --dev-bind-try /dev/nvidia0 /dev/nvidia0 \
  --dev-bind-try /dev/nvidiactl /dev/nvidiactl \
  --dev-bind-try /dev/nvidia-uvm /dev/nvidia-uvm

Alternative Solutions

The only way around this I've found is to disable sandboxing, which is unfortunate. I'd love to use sandboxing instead of needing to run things through docker (where I can then do GPU passthrough but with much more pain).

Priority

Critical - Blocking my work

Feature Category

Configuration and settings

Use Case Example

My primary use is developing GPU-accelerated code with Claude Code in sandbox mode. I want to automate kernel authoring, fine-tuning/optimization, and correctness testing as well as run my existing test suites (pytorch CUDA/ROCM, ONNX, vLLM, etc).

There's a few other things we use as well (namely ffmpeg as part of image pipelines), but there's quite a bit of popular GPU-accelerated tools that cannot run properly in sandbox mode which would be generally useful:

| Software | Use Case | Blocked By |
|-----------------------|------------------------------|------------------------|
| PyTorch | ML training/inference | /dev/kfd, /dev/nvidia* |
| TensorFlow | ML training/inference | /dev/kfd, /dev/nvidia* |
| JAX | ML research | /dev/kfd, /dev/nvidia* |
| IREE | ML compiler runtime | /dev/kfd, /dev/dri |
| Blender | 3D rendering (Cycles) | /dev/dri, /dev/nvidia* |
| FFmpeg | Video encoding (VAAPI/NVENC) | /dev/dri, /dev/nvidia* |
| darktable/RawTherapee | Photo processing (OpenCL) | /dev/dri |

Concretely, I want to enable the sandbox and then have Claude be able to run directly or indirectly via scripts/tools commands like:

python3 -c "import torch; print(torch.cuda.is_available())"      # NVIDIA
python3 -c "import torch; print(torch.hip.is_available())"       # AMD

Additional Context

Prior Art

Flatpak uses identical bwrap flags for GPU-accelerated sandboxed apps:

Common GPU device nodes:
| Device | Purpose |
|-------------------|-------------------------------------|
| /dev/dri/card* | DRM display devices |
| /dev/dri/renderD* | GPU compute/render (Vulkan, OpenGL) |
| /dev/kfd | AMD ROCm/HIP kernel driver |
| /dev/nvidia* | NVIDIA CUDA/driver |

Technical Considerations

  1. Security: Device access is read/write to GPU hardware only - no filesystem escape. Flatpak considers --device=dri a https://docs.flatpak.org/en/latest/sandbox-permissions.html safe for general use.
  2. Ordering: bwrap processes args in order. Device binds should come before --dev /dev to avoid shadowing (https://github.com/containers/bubblewrap/issues/248).
  3. PCI sysfs: Some GPU tools also need read-only access to /sys/bus/pci and /sys/devices/pci* for device enumeration (https://wiki.alpinelinux.org/wiki/Bubblewrap/Examples).
  4. Graceful degradation: --dev-bind-try (not --dev-bind) ensures systems without GPUs don't error.

References

Test Cases

These commands should work in sandbox mode with GPU passthrough:

# AMD ROCm/HIP
rocm-smi --showid                    # List AMD GPUs
rocminfo                             # ROCm device info
hipconfig --version                  # HIP configuration
clinfo                               # OpenCL devices

# NVIDIA CUDA
nvidia-smi                           # List NVIDIA GPUs
nvcc --version                       # CUDA compiler

# Vulkan (vendor-agnostic)
vulkaninfo --summary                 # Should show real GPU, not llvmpipe
vkcube                               # Vulkan test cube

# OpenGL
glxinfo | grep "OpenGL renderer"     # Should show GPU, not llvmpipe

# Simple compute test
python3 -c "import torch; print(torch.cuda.is_available())"      # NVIDIA
python3 -c "import torch; print(torch.hip.is_available())"       # AMD

View original on GitHub ↗

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