Skip to main content

Sandbox Isolation

Ash treats agent code as untrusted. Each agent session runs inside an isolated sandbox process with restricted access to the host system.

Security Model

The agent inside the sandbox can execute arbitrary shell commands (that is how the Claude Code SDK works). The sandbox must prevent:

  • Reading host environment variables (credentials, secrets)
  • Writing outside the workspace directory
  • Consuming unbounded host resources (memory, CPU, disk)
  • Interfering with other sandboxes or the host process

Isolation Layers

LayerLinuxmacOS (dev)
Process limitscgroups v2ulimit
Memory limitcgroup memory.max (default 2048 MB)ulimit (best-effort)
CPU limitcgroup cpu.max (default 100% = 1 core)Not enforced
Disk limitPeriodic check, kill on exceed (default 1024 MB)Periodic check, kill on exceed
Max processescgroup pids.max (default 64, fork bomb protection)ulimit
EnvironmentStrict allowlistStrict allowlist
Filesystembubblewrap (bwrap) read-only root, writable workspaceRestricted cwd only
NetworkNetwork namespace (configurable)Unrestricted

Resource limit defaults are defined in @ash-ai/shared:

const DEFAULT_SANDBOX_LIMITS = {
memoryMb: 2048, // Max RSS in MB
cpuPercent: 100, // 100 = 1 core
diskMb: 1024, // Max workspace size in MB
maxProcesses: 64, // Fork bomb protection
};

Environment Variable Allowlist

The sandbox process receives only these environment variables. Everything else is blocked.

Passed through from host (if set)

VariablePurpose
PATHStandard path
NODE_PATHNode.js module resolution
HOMEHome directory (set to workspace dir)
LANGLocale
TERMTerminal type
ANTHROPIC_API_KEYRequired for Claude Code SDK
ASH_DEBUG_TIMINGEnable timing instrumentation

Injected by Ash

VariablePurpose
ASH_BRIDGE_SOCKETPath to the Unix socket for bridge communication
ASH_AGENT_DIROriginal agent directory path
ASH_WORKSPACE_DIRWritable workspace directory for this session
ASH_SANDBOX_IDUnique sandbox identifier
ASH_SESSION_IDSession identifier

Everything else: blocked

The sandbox does not inherit process.env. Variables like AWS_SECRET_ACCESS_KEY, DATABASE_URL, GITHUB_TOKEN, or any other host secret are never visible inside the sandbox.

// From sandbox/manager.ts -- allowlist enforcement
const env: Record<string, string> = {};
for (const key of SANDBOX_ENV_ALLOWLIST) {
if (process.env[key]) {
env[key] = process.env[key]!;
}
}
// Only these vars + injected ASH_* vars are passed to the child process

OOM Detection

When a sandbox process is killed by the kernel's OOM killer (exit code 137 or SIGKILL), Ash detects this and automatically pauses the session. The session can be resumed later with a fresh sandbox.

Disk Monitoring

A periodic check (every 30 seconds) measures the workspace directory size. If it exceeds diskMb, the sandbox is killed immediately.