Stashbase

Overview

Run agents inside an isolated container with a network-layer firewall

The Docker backend runs stashbase agent run inside an isolated container instead of a sandboxed process on the host. It is stronger than the default native backend (Seatbelt on macOS, systemd-run or bubblewrap on Linux) in four ways:

  • Filesystem: allow-list instead of deny-list. Only the working directory is visible inside the container.
  • Network: a firewall inside the container's network namespace enforces egress. A process that ignores HTTPS_PROXY/HTTP_PROXY and opens a raw socket is blocked just like one that respects them.
  • Platforms: works on macOS, Linux, and Windows (via Docker Desktop). The native backend does not support Windows.
  • Extensible: add the tools your agent needs with your own image or Dockerfile without weakening the sandbox.

The native backend remains the default because it needs nothing beyond the CLI. If Docker is available, use the Docker backend.

Enable the Docker backend

.stashbase/agents/coding.toml
[sandbox]
backend = "docker"

To override the profile's backend for a single run:

stashbase agent run --profile coding --docker-sandbox true -- claude   # force Docker
stashbase agent run --profile coding --docker-sandbox false -- claude  # force native

--docker-sandbox changes only the backend. Secrets, egress rules, and filesystem rules still come from the profile. If Docker isn't installed or the daemon isn't running, the run fails closed. It does not fall back to the native backend or run without a sandbox.

What is enforced

Filesystem. Only the current working directory is mounted. deny_read and deny_write paths outside it are already invisible. Paths inside it are shadow-mounted: deny_read paths are mounted empty and deny_write paths read-only.

Network. Each run gets its own Docker network, and the container can reach only the Stashbase Agent Proxy. The LAN, host services, and other local processes are unreachable. A short-lived holder container installs an iptables default-DROP rule and checks that it works before the agent starts. If the check fails, the run doesn't start. The agent container shares that network namespace but holds no capabilities, so it cannot change the rule. DNS is disabled entirely, which closes DNS-based exfiltration. host.docker.internal still resolves through /etc/hosts.

Process hardening. The agent container always runs with --cap-drop ALL, no-new-privileges, --init, and --pids-limit 2048. These settings can't be configured or disabled.

Limitations

  • Each run starts two containers (the firewall holder and the agent), which adds some startup overhead.
  • The login volume is shared by every Docker-backend profile on the machine, so chat history and config from one profile are visible to others. This affects privacy, not security: egress and credential policy are still enforced separately for each run.

Next steps

See Filesystem restrictions for the native backend and Run and secure agents for the broader security boundary.

On this page