Sandbox configuration
config/sandbox.toml configures how the exec tool runs commands. It is optional; the default backend is Bubblewrap.
toml
backend = "bwrap"
mounts = []
[bwrap]
binaries = ["git", "python3"]Backends
backend selects bwrap (default) or incus.
bwrap— a fresh Linux namespace sandbox for each command.incus— one persistent system container per agent.
Mounts
mounts exposes host directories inside the sandbox below /workspace/.
toml
[[mounts]]
source = "/home/user/projects/my-app"
target = "project"
mode = "rw"Mount sources must be absolute paths or begin with ~/. Mount targets are relative paths below /workspace/ and are ro or rw. Mount targets must not overlap; configure sibling targets rather than nesting one below another.
Bubblewrap
[bwrap] binaries is an allowlist of host commands made available to exec. Commands containing shell metacharacters or spaces are rejected; arguments are passed separately.
Filesystem
Each command receives the standard paths:
/workspace— read-write agent workspace./memories— read-write agent memories./blocks— read-only agent blocks./skills— read-write agent skills./tasks— read-write agent tasks./tmp— fresh 64 MiB temporary filesystem./procand/dev— minimal sandbox pseudo-filesystems.
Custom mounts appear below /workspace/. Host account files, certificates, and required system libraries are exposed read-only so configured commands can run.
Commands start in /workspace with HOME=/workspace. The environment is rebuilt with a minimal PATH, locale settings, values from workspace/.env, and configured passthrough variables.
Devices
Device access is opt-in.
toml
[devices]
usb = true
all = trueall exposes the host /dev and is substantially broader than usb.
NixOS
On NixOS, the configured binaries and their Nix store requisites are resolved and bound into the sandbox.
Incus
backend = "incus" requires a [incus] table.
toml
backend = "incus"
[incus]
image = "images:fedora/42"
profiles = []
# project = "cireilclaw"
# shutdownOnExit = falseimage— any image reference accepted by the Incus server.profiles— optional profiles applied when the instance is created.project— optional Incus project; defaults to the caller's current project.shutdownOnExit— whether the runtime stops the agent's instance when the runtime host exits; defaults totrue.
The instance name is cireilclaw-{agent-slug}. The first command creates and starts the instance; the runtime stops active instances during shutdown unless shutdownOnExit = false. Instances are not destroyed on normal shutdown, so installed packages and container-local state persist. With shutdownOnExit = false the instance keeps running after the host exits, so a later run reuses the running instance instead of stopping and starting it.
Agent directories are mounted into the instance, and the host process UID and GID are mapped into the container so commands run as the host identity rather than container root. The runtime may use root inside the container during setup to create the mapped account and configure passwordless sudo.
The runtime user must be able to access the Incus Unix socket. Restricted projects must permit raw.idmap and the runtime UID and GID.
Disabling the sandbox
The environment variable CIREILCLAW_RUNTIME_INSECURE_DISABLE_SANDBOX_I_AM_100_PERCENT_SURE bypasses Bubblewrap and runs commands directly on the host. The documented bypass value is exactly i-am-in-a-container. The source also accepts babe-i-brought-protection and we-are-literally-transbians-what as intentional easter eggs retained for source parity. All three values are explicit insecure opt-ins; any other value leaves the sandbox in place. Disabling the sandbox does not make arbitrary commands safe.
Security model
The sandbox is the least-privilege command boundary between an agent and the host. The boundary depends on Linux namespaces, bind mounts, the configured binary allowlist, and the security of the host bwrap installation and kernel.
exec is not the same boundary as conditional file-access rules: once a command is allowed to run, it can inspect, copy, or transform anything visible inside its sandbox.
The runtime's own reads and writes of agent areas and mounts are contained by the kernel. Each access opens the target with openat2(2) relative to the area or mount root and refuses any resolution that leaves it, so a process inside the sandbox cannot redirect the runtime's file access by replacing a path component with a symbolic link between the check and the access. Symbolic links are followed while they resolve inside the same area or mount; absolute link targets and links that leave it are refused. Every file tool, attachment download, heartbeat checklist read, skill load, environment-file read, and legacy migration access follows this rule, and the checked boundary is the same object the access acts on rather than a host path string that is resolved again later. The boundary root is re-verified on each access, so a mount source reachable through another mount cannot be moved and replaced with a symbolic link under the runtime. Sandbox file access requires kernel support for openat2(2) (Linux 5.6 or newer) and reports a platform error elsewhere.
Plugins are not placed inside this sandbox; plugin code is trusted runtime code, and ctx.paths.resolve reports the host path a sandbox path maps to without resolving symbolic links.
Reload
The runtime watches sandbox.toml and applies changes live to subsequent commands.