Sandbox Modes
AgentVisor™ supports multiple sandbox modes. Docker and gVisor are both production-grade; gVisor adds syscall-level interception for slightly stronger defense-in-depth and is the default for built images. Docker runs on any platform that supports Docker.
A sandbox is a security isolation boundary — a hardened execution environment where agent code runs fully isolated from the host with no direct access to the network, filesystem, processes, or credentials. This is a production-grade boundary, not a test environment.
The sandbox is the substrate for confinement, not a substitute for it. Isolation is what makes mediation non-bypassable; together with credential brokering, policy decisions on every outbound effect, and a host-side record, it yields a confined agent.
Overview
| Mode | Platform | Isolation Level | Hardening | Notes |
|---|---|---|---|---|
gvisor | Linux | Container + Syscall interception | Full | Strongest isolation; default for built images |
docker | Linux | Container | Full | Cross-platform; production-grade |
docker | macOS/Windows | Container | Full† | Same posture as Docker/Linux; outbound restriction via in-guest nftables |
none | Any | None | None | No isolation; agent development and debugging only |
†Docker on macOS/Windows uses network_filtering (in-guest nftables) instead of --network=none because TCP transport to host.docker.internal is required. The agent's effective outbound network restriction is equivalent.
gVisor Mode Linux Only
Syscall-level isolation — strongest security available, recommended for Linux production deployments.
gVisor is the default sandbox mode when deploying containers built with agentvisor build. It is recommended for Linux production deployments where slightly stronger isolation is preferred.
agentvisor serve ./my-agent --sandbox=gvisor
# Interactive terminal session with gVisor isolation
agentvisor exec ./my-agent --sandbox=gvisor
Container images built with agentvisor build already include gVisor — you get gVisor sandbox isolation on any platform through the normal build and deploy flow.
Installing gVisor's runsc locally is only needed if you want to run agentvisor serve --sandbox=gvisor directly on a Linux workstation:
curl -fsSL https://gvisor.dev/archive.key | sudo apt-key add -
sudo add-apt-repository "deb https://storage.googleapis.com/gvisor/releases release main"
sudo apt-get update && sudo apt-get install runsc
| Platform | agentvisor build (gVisor) | Local --sandbox=gvisor |
|---|---|---|
| macOS (Intel/Apple Silicon) | Yes | No |
| Windows (with Docker Desktop) | Yes | No |
| Linux (x86_64/arm64) | Yes | Yes |
How It Works
- Host runtime creates OCI bundle
- runsc (gVisor runtime) spawns sandbox
- Sentry (userspace kernel) intercepts all syscalls
- Network disabled, only Unix socket available
Isolation Features
gVisor provides a userspace kernel (Sentry) that intercepts every syscall before it reaches the host kernel. AgentVisor layers additional hardening on top:
From gVisor:
- Syscall interception: Every syscall goes through Sentry
- No direct kernel access: Kernel vulnerabilities don't expose host
Added by AgentVisor:
- Network isolation:
network=noneconfiguration — no network interface in the sandbox - Resource limits: cgroups v2 enforcement of
memory_limit,cpu_limitandpids_limit, governed by theresource_limitshardening group. Always on indockermode. Ingvisormode it needs the host runtime to run as root with a writable cgroup v2 mount (typically a privileged container); otherwise set the limits on the container or pod running the host runtime - Privilege separation: OpenSSH-style privsep with UID 2000 main process
- Per-agent UID isolation: Unique UIDs (2001+) prevent cross-tenant memory reads
- Environment curation: Allowlist for system env vars, blocklist for user-supplied vars
Advantages
- Strongest isolation available
- Kernel vulnerabilities don't affect host
- Comprehensive syscall filtering
- Defense in depth
Privilege Modes
gVisor can run in two modes: rootless (default) or privileged.
Rootless Mode (Default)
gVisor creates a user namespace internally via CLONE_NEWUSER combined with --network=none. Container images built with agentvisor build have uidmap and subuid/subgid pre-configured for this.
Rootless mode requires unprivileged user namespaces enabled on the host kernel:
- Linux 5.15+ supports this by default on most distributions
- Some distributions (Debian, Ubuntu 23.10+) require:
sysctl -w kernel.unprivileged_userns_clone=1 - Verify with:
cat /proc/sys/user/max_user_namespaces(should be> 0)
These prerequisites only matter when running runsc directly on a host; container images from agentvisor build handle the rest.
# CLI — rootless is the default
agentvisor serve ./my-agent --sandbox=gvisor
# Docker — both flags required: seccomp and AppArmor can each block CLONE_NEWUSER
docker run --security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
my-agent:v1
Privileged Mode
Opt-in mode that requires Docker --privileged. Provides full gVisor capabilities with maximum defense-in-depth, including DirectFS for fastest I/O.
# CLI — opt in with --rootless=false
agentvisor serve ./my-agent --sandbox=gvisor --rootless=false
# Docker — must run as root with --privileged
docker run --user root --privileged -p 8090:8090 -e AGENTVISOR_GUEST_ROOTLESS=false my-agent:v1
Mode trade-offs:
| Aspect | Rootless (default) | Privileged |
|---|---|---|
| Docker flags | --security-opt seccomp=unconfined --security-opt apparmor=unconfined | --user root --privileged |
| Filesystem | 9P filesystem (slower) | DirectFS (fastest) |
| Defense in depth | Reduced (per gVisor docs) | Full |
| Privilege required | None (zero-capability) | Root-equivalent |
| Kernel prerequisites | Unprivileged userns + uidmap | None |
In rootless mode (default), the process never starts as root — no privilege is required or dropped. In privileged mode, the host runtime starts as root only to initialize the gVisor sandbox, then permanently drops privileges to uid/gid 1000 (unprivileged agentvisor user) via irreversible setuid()/setgid() syscalls. All subsequent operations run as the unprivileged user.
- When maximum I/O performance (DirectFS) is required
- On hosts without unprivileged user namespace support
- When your environment already allows
--privilegedand you want full defense-in-depth
- Performance: Uses 9P filesystem instead of DirectFS
- Symlinks: Container root path must not contain symlinks
- Isolation: Some defense-in-depth guarantees are reduced per gVisor documentation
When to Use
- Production deployments
- Multi-tenant environments
- Running untrusted code
- Regulated industries
Docker Mode
Docker container isolation — a production-grade isolation boundary that runs the guest in a Docker container.
Docker is the default sandbox mode for agentvisor run, agentvisor serve, and agentvisor exec because it works on any platform (Linux, macOS, Windows) without extra host setup.
agentvisor serve ./my-agent
How It Works
- Host runtime starts on the host machine
- Guest container started via Docker API
- Host and guest communicate over a hostlink session, carried by UDS on Linux or TCP+mTLS on macOS/Windows (see Hostlink Transport below)
- Agent runs inside the container
Hostlink Transport
The hostlink session (see Architecture) is the multiplexed gRPC connection between the host runtime and the guest sandbox. By default (guest.docker_transport: auto), the wire-level transport depends on host OS:
- Linux: Unix domain socket bind-mounted into the container. OS-level isolation; no TLS needed.
- macOS / Windows: TCP + mTLS via
host.docker.internal. UDS bind-mounts don't cross the Docker Desktop VM boundary, so AgentVisor falls back to TCP — and mTLS keeps the channel authenticated and encrypted across that boundary. The mTLS credentials are short-lived and scoped to the sandbox lifetime.
Remote or Sibling Docker Daemon
A Linux host isn't always a guarantee that the Docker daemon shares a filesystem with the
host runtime — a remote Docker daemon, or a sibling daemon reached over DOCKER_HOST
(for example, a Docker-in-Docker CI topology), can't see a UDS bind-mount created outside
its own container, even though the host reports Linux. Two config keys make the transport
and advertised host address explicit instead of relying on OS auto-detection:
guest.docker_transport(AGENTVISOR_GUEST_DOCKER_TRANSPORT):auto(default, GOOS-based as above),uds(force UDS), ortcp(force TCP + mTLS even on Linux).guest.host_link_advertise_host(AGENTVISOR_GUEST_HOST_LINK_ADVERTISE_HOST): the address the guest dials back to reach the host when TCP transport is selected. Empty (default) keepshost.docker.internal; set this when the daemon reaches the host runtime under a different name.
When docker_transport: tcp is selected explicitly (rather than via the macOS/Windows
auto-path), the hostlink listener binds all interfaces instead of loopback-only, since a
remote or sibling daemon is a real network peer rather than a VM-proxied guest — mTLS
remains the access control in that case. There is no automatic discovery of a working
host_link_advertise_host value for a given topology; an incorrect value fails the
connection rather than silently falling back to a guess.
Advantages
- Works on macOS, Windows, and Linux
- Container-level isolation
- Uses familiar Docker tooling
- Default mode — no extra flags needed
Limitations
- Uses TCP instead of Unix sockets on macOS/Windows (Docker Desktop VM limitation)
- Docker Desktop VM overhead on non-Linux platforms
- Does not include syscall-level interception (use gVisor on Linux if that layer matters)
When to Use
- Development and production on any platform that supports Docker
- Cross-platform deployments (Linux, macOS, Windows)
- CI/CD environments
- Production on non-Linux hosts (or Linux hosts where gVisor's runsc is not available)
Unsandboxed Mode
No isolation — runs the agent directly in your local environment. Mediation is bypassable in this mode, so the agent is unconfined.
agentvisor serve ./my-agent --sandbox=none
Running with --sandbox=none requires a Python virtual environment with the AgentVisor SDK installed. See Local Development Setup for complete setup instructions.
How It Works
- Host runtime starts directly (no container)
- Agent process spawned as a child process
- HTTP proxy runs in the same process
- Policy enforcement still applies
Advantages
- Fast startup
- Easy debugging with standard tools
- No container overhead
- Works on any platform
Limitations
- No security isolation
- Agent has full filesystem access
- Agent could bypass proxy (if malicious)
- Requires manual environment setup (e.g., Python venv for LangGraph agents)
When to Use
- Debugging agent code
- Quick iteration with breakpoints
- When Docker is not available
Granular Hardening
AgentVisor's security hardening is organized into seven feature groups. Each group defaults to auto, which enables features when supported by the sandbox type.
You may see AgentVisor's sandbox security described with three different numbers. Each counts
the same defense-in-depth architecture at a different level of granularity: 7 feature groups
here (the independently-configurable guest.hardening knobs), 12 implementation-level
hardening mechanisms enumerated in Guest Sandbox
Hardening (several groups above cover more than
one mechanism), and 14 independent security layers in Why
AgentVisor — a broader, product-level count that
also includes protections outside guest.hardening's scope entirely, such as credential
brokering and stdio MCP server sandboxing. None of these numbers contradicts another.
Hardening Feature Groups
| Feature Group | What It Controls |
|---|---|
process_isolation | Privilege separation, UID isolation, capability dropping |
env_curation | Environment variable curation (allowlist for system env, blocklist for user vars), umask 0077 |
network_isolation | Loopback-only networking (--network=none) |
network_filtering | In-guest nftables ruleset restricting outbound traffic to loopback + hostlink only |
filesystem_hardening | Read-only rootfs, seccomp profiles, tmpfs mounts |
kernel_hardening | Capability bounding set, NoNewPrivileges, user namespace blocking |
resource_limits | Enforcement of the sandbox-wide memory_limit, cpu_limit and pids_limit through cgroups |
Configuration Values
| Value | Behavior |
|---|---|
auto | Enable if supported by sandbox type (default) |
enabled | Force enable — fails startup if not supported |
disabled | Force disable — WARNING logged |
Auto-Detection Matrix
| Sandbox Type | Platform | process_isolation | env_curation | network_isolation | network_filtering | filesystem_hardening | kernel_hardening | resource_limits |
|---|---|---|---|---|---|---|---|---|
gvisor | Linux | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓† |
docker | Linux | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ |
docker | macOS/Windows | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ |
none | Any | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
† gvisor enforces the sandbox-wide limits only when the host runtime runs as root with a writable
cgroup v2 mount (for example a privileged container), so resource_limits: auto resolves to off in
the default rootless deployment. enabled fails startup there instead.
network_isolation and network_filtering are mutually exclusive: Linux modes use --network=none (OS-level); Docker on macOS/Windows uses in-guest nftables instead, achieving equivalent outbound restriction.
Configuration Example
guest:
hardening:
process_isolation: auto # AGENTVISOR_GUEST_HARDENING_PROCESS_ISOLATION
env_curation: auto # AGENTVISOR_GUEST_HARDENING_ENV_CURATION
network_isolation: auto # AGENTVISOR_GUEST_HARDENING_NETWORK_ISOLATION
network_filtering: auto # AGENTVISOR_GUEST_HARDENING_NETWORK_FILTERING
filesystem_hardening: auto # AGENTVISOR_GUEST_HARDENING_FILESYSTEM_HARDENING
kernel_hardening: auto # AGENTVISOR_GUEST_HARDENING_KERNEL_HARDENING
resource_limits: auto # AGENTVISOR_GUEST_HARDENING_RESOURCE_LIMITS
The auto setting is recommended for most deployments. It enables all hardening features supported by your sandbox type without manual configuration.
Comparison
Note: Both
dockerandgvisorare production-grade. The difference is that gVisor adds a userspace kernel that intercepts every syscall, while Docker relies on container isolation and seccomp filtering.nonehas no isolation and is for local development only.
Configuration
Startup/shutdown timeouts are available in gvisor and docker modes.
Resource limits (memory_limit, cpu_limit, pids_limit) apply to the sandbox as a whole and are
governed by the resource_limits hardening setting. In docker mode they map to Docker's
--memory/--cpus/--pids-limit flags. In gvisor mode they are enforced through a cgroup that the
host runtime hands to runsc, which requires the host runtime to run as root with a writable cgroup v2
mount (for example a privileged container). In the default rootless deployment that is not available:
resource_limits: auto resolves to off, the startup log shows resource_limits=false, and a warning
names any limit you changed. Apply memory, CPU and process limits to the container or pod that runs the
host runtime instead (for example Kubernetes resource limits or docker run --memory), or set
resource_limits: enabled to fail startup rather than run without them.
memory_limit is a hard cap on memory plus swap: a sandbox that exceeds it is killed, not paged out. cpu_limit is a number of CPUs
(0.5 = half a CPU). In gvisor mode pids_limit counts the sandbox's host threads rather than the
processes inside it, and exceeding it stops the whole sandbox, so keep it generous. Process count per
agent run is separately bounded by nproc_soft_limit/nproc_hard_limit.
See the Configuration Reference for the full environment variable list.
Docker/Kubernetes Deployment
For container deployments, the sandbox mode is configured via environment variable. Images built with agentvisor build default to gVisor, so AGENTVISOR_GUEST_SANDBOX can be omitted unless you need to override it.
Rootless Mode (Default)
No extra capabilities required. Images built with agentvisor build work out of the box:
# docker-compose.yml (rootless — default)
services:
agentvisor:
image: my-agent:v1
security_opt:
- seccomp=unconfined # Required: default seccomp profile may block CLONE_NEWUSER
- apparmor=unconfined # Required on Ubuntu 24.04+, GKE, AKS
ports:
- "8090:8090"
# Kubernetes deployment (rootless — default)
apiVersion: v1
kind: Pod
spec:
containers:
- name: agent
image: my-agent:v1
securityContext:
seccompProfile:
type: Unconfined # Required: default seccomp profile may block CLONE_NEWUSER
appArmorProfile:
type: Unconfined # Required on Ubuntu 24.04+, GKE, AKS
Privileged Mode
Opt-in when you need DirectFS performance or lack unprivileged user namespace support:
# docker-compose.yml (privileged)
services:
agentvisor:
image: my-agent:v1
user: root
privileged: true
environment:
- AGENTVISOR_GUEST_ROOTLESS=false
# Kubernetes deployment (privileged)
apiVersion: v1
kind: Pod
spec:
containers:
- name: agent
securityContext:
privileged: true
runAsUser: 0
env:
- name: AGENTVISOR_GUEST_ROOTLESS
value: "false"
Choosing a Mode
| Scenario | Recommended Mode |
|---|---|
| Local development (default) | docker |
| Debugging/breakpoints | none |
| Production on Linux (strongest isolation) | gvisor |
| Production on non-Linux / cross-platform | docker |
| Multi-tenant SaaS on Linux | gvisor |
| CI/CD testing | docker |
| Interactive sessions (exec) | docker or gvisor |