Configure the network egress jail#

The jail is on by default. It blocks private, link-local and connected networks, and the cloud metadata addresses, while allowing internet access, DNS and explicitly allowed IPs. Routes your host or VPN adds for internal networks are not carried into the jail: it rebuilds its route table from that allowlist alone and checks it before the agent starts. Agents get a private IPv4-only network namespace; ordinary container shells do not.

With the PyPI launcher, edit ~/.config/claude-sandbox.conf on the host. Follow container configuration to mount it. In your own devcontainer, edit /etc/claude-sandbox.conf from a terminal outside the agent, and reapply changes after rebuilding or reinstalling.

Add the one required container device#

The PyPI launcher supplies /dev/net/tun automatically. For your own devcontainer, add this run argument and rebuild:

"runArgs": ["--device=/dev/net/tun"]

Missing tun, pasta or namespace support makes agent launch fail closed. The install, the published image’s start and claude-sandbox doctor warn about a missing /dev/net/tun earlier, while the jail is on. Use rootless Podman: rootful Docker cannot host the default jail.

The devcontainer’s base image must also have passt 0.0~git20230908 or later. Debian 12’s (0.0~git20230309, in node:22-slim and other bookworm images) fails twice. It installs pasta as a symlink to passt, so on a host that enforces AppArmor, as Ubuntu hosts do, the profile for passt confines it, and it cannot attach to the agent’s namespace. Where it does attach, it sets up a broadcast route that the jail’s route check refuses. bookworm-backports has no newer passt. Ubuntu 24.04 (0.0~git20240220) and Debian 13 (0.0~git20250503) images work, for example node:22-trixie-slim in place of node:22-slim. The install and claude-sandbox doctor warn about an older passt while the jail is on, and the launch refuses and names the cause.

Keep a lab device or internal forge reachable#

Add one bare IP per line:

allow-ip = 172.23.1.3

This grants access to that device, not just one service. Review each addition.

Note

DLS: Diamond GitLab The shipped config includes allow-ip = 172.23.142.119 for Diamond GitLab. Retain that line if you replace the config and need forge access. Authentication alone does not make a blocked internal IP reachable.

Reach services on the host’s loopback#

Use a relay port for services on 127.0.0.1; allow-ip does not route loopback into the jail:

local-port = 5432

The shipped local-model-port = 1920 relays lllm2’s API for every agent and enables Pi’s model discovery. Other ports use repeatable local-port lines. Every relayed port exposes the whole service behind it.

The outer container must share the service’s network namespace. The PyPI launcher uses host networking by default; --bridge prevents its loopback from reaching host-local services. A custom devcontainer needs host networking when the service runs on the host.

Let a browser login reach the agent#

A callback relay lets a host browser reach a login server inside the agent’s private loopback. Enable only the fixed ports you need:

callback-port = 53692   # Pi's Claude subscription login
callback-port = 1455    # Codex browser login

The shipped examples are commented out. Ports cannot overlap local-port or local-model-port. If a host port is already occupied, the session warns and skips that relay; use the provider’s paste-code, callback-URL or device-login alternative where available.

The browser must reach the outer container’s loopback. For a remote machine, forward the port through your editor or SSH. Claude Code’s variable callback port uses its code-paste flow instead of a fixed relay.

A note on Channel Access for Claude#

Warning

DLS: Channel Access needs unicast LAN broadcast discovery does not cross the agent’s private network namespace. Set EPICS_CA_ADDR_LIST to the device IPs, forward it with pass-env, and allow each IP with allow-ip. Ordinary shells in a host-network container retain broadcast access.

See Configuration for all keys and overrides, and the threat model for what the jail does and does not protect.