Sandbox Profiles Reference

Sandbox profiles define runtime, network, SSH passthrough, mounts, and resource limits for container sandboxing.

This guide is focused on Linux and macOS. Windows is not tested yet for this workflow. Contributions are welcome.

Profile location

<config>/sandboxes/<profile-name>.json

Example: <config>/sandboxes/dev.json (see Application Directories)

Built-in profile files are created automatically when profile loading is used.

Loading profiles

# Load profile
llxprt --sandbox-profile-load dev

# Override runtime engine
llxprt --sandbox-engine podman --sandbox-profile-load dev

# Disable sandboxing
llxprt --sandbox-engine none

Important behavior: loading a profile implies sandbox intent, even without --sandbox.

Built-in profiles

dev

{
  "engine": "auto",
  "image": "ghcr.io/vybestack/llxprt-code/sandbox:<version>",
  "resources": { "cpus": 2, "memory": "4g", "pids": 256 },
  "network": "on",
  "sshAgent": "auto",
  "mounts": [],
  "env": {}
}

Use for normal development.

safe

{
  "engine": "auto",
  "image": "ghcr.io/vybestack/llxprt-code/sandbox:<version>",
  "resources": { "cpus": 2, "memory": "4g", "pids": 128 },
  "network": "off",
  "sshAgent": "off",
  "mounts": [],
  "env": {}
}

Use for untrusted code review.

tight

{
  "engine": "auto",
  "image": "ghcr.io/vybestack/llxprt-code/sandbox:<version>",
  "resources": { "cpus": 1, "memory": "2g", "pids": 64 },
  "network": "off",
  "sshAgent": "off",
  "mounts": [],
  "env": {}
}

Use for strict isolation.

offline

{
  "engine": "auto",
  "image": "ghcr.io/vybestack/llxprt-code/sandbox:<version>",
  "resources": { "cpus": 2, "memory": "4g", "pids": 128 },
  "network": "off",
  "sshAgent": "off",
  "mounts": [],
  "env": {}
}

Use for local/offline workflows.

Schema

engine

Type: "auto" | "docker" | "podman" | "sandbox-exec" | "none"

  • auto: picks available runtime
  • docker: force Docker
  • podman: force Podman
  • sandbox-exec: macOS Seatbelt
  • none: disable sandboxing

image

Type: string

Defaults to the current release image configured in package metadata (config.sandboxImageUri).

You can provide your own image if it includes required utilities (git, bash, and socat for Podman macOS bridge paths).

resources

{
  "resources": {
    "cpus": 4,
    "memory": "8g",
    "pids": 512
  }
}
  • cpus: CPU limit
  • memory: memory limit
  • pids: process count limit

Podman on macOS: The memory value must not exceed the Podman machine VM memory. On macOS, Podman runs containers inside a Linux VM, and the VM memory is the hard ceiling. If memory exceeds VM memory, the container starts but gets OOM-killed (exit code 137). See Sandbox troubleshooting for how to inspect and resize VM memory.

network

Type: "on" | "off" | "proxied"

  • on: default networking
  • off: launches container with network disabled
  • proxied: requires a non-whitespace LLXPRT_SANDBOX_PROXY_COMMAND. Docker and Podman use the existing isolated sandbox network plus proxy-container network; invalid configuration fails before setup or launch. Seatbelt selects its built-in permissive proxied profile unless a non-empty SEATBELT_PROFILE explicitly overrides profile selection.

Network environment precedence is nullish: LLXPRT_SANDBOX_NETWORK wins when defined, including when it is an empty string; otherwise SANDBOX_NETWORK is used. In Seatbelt mode, off, proxied, and all other values map to permissive-closed, permissive-proxied, and permissive-open, respectively. A non-empty SEATBELT_PROFILE remains the exact explicit built-in or custom profile override. The built-in permissive-proxied and restrictive-proxied profiles still require the proxy command.

On Linux, off remains compatible with the direct mounted Unix credential socket. On macOS, Docker and Podman credential bridges require networking, so off fails before credential proxy or container resources are started; enable networking or use Linux for network-off sandboxing.

sshAgent

Type: "auto" | "on" | "off"

  • auto: enable if SSH_AUTH_SOCK exists
  • on: require/attempt setup and warn if unavailable
  • off: disable passthrough

mounts

{
  "mounts": [
    { "from": "~/.npmrc", "to": "/home/node/.npmrc", "mode": "ro" },
    { "from": "~/shared", "to": "/shared" }
  ]
}

Mount object:

  • from: host path (~ expansion supported)
  • to: container path (defaults to same path as from)
  • mode: "ro" | "rw" (defaults to "ro")

env

{
  "env": {
    "NPM_CONFIG_REGISTRY": "https://registry.npmjs.org"
  }
}

Adds environment variables to sandbox launch context.

Engine selection notes

When engine is auto, fallback preference is:

  1. Docker
  2. Podman
  3. sandbox-exec (macOS)
  4. no sandbox (if nothing available)

Notes:

  • With --sandbox-profile-load, this fallback list is used directly.
  • With --sandbox on macOS, base command detection checks sandbox-exec first, then Docker, then Podman.
  • You can always force engine with --sandbox-engine.

Podman macOS notes

Podman runs in a VM on macOS, so there are extra constraints:

  • launchd SSH socket paths are often unusable in VM bridge paths
  • SSH and credential proxy bridges require --network=host
  • an existing non-host --network value causes optional SSH forwarding to warn and return before connection lookup or tunnel allocation; credential bridge conflicts remain fatal
  • VM memory must exceed the container resources.memory limit, or the process gets OOM-killed (exit code 137). See Sandbox troubleshooting.

If SSH forwarding is unreliable, use a dedicated socket path (the location is your choice — this example uses a path in your home directory):

ssh-agent -a ~/.ssh/llxprt-agent.sock
export SSH_AUTH_SOCK=~/.ssh/llxprt-agent.sock
ssh-add ~/.ssh/id_ed25519

Listing and inspecting profiles

Sandbox profiles live in <config>/sandboxes/ (see Application Directories). The config directory is overridable via LLXPRT_CONFIG_HOME and follows the platform default (~/.config/llxprt-code on Linux, ~/Library/Preferences/llxprt-code on macOS, %APPDATA%\llxprt-code\Config on Windows).

Set a shell variable for convenience:

# Linux / macOS
SANDBOX_DIR="${LLXPRT_CONFIG_HOME:-$(node --input-type=module -e "import envPaths from 'env-paths'; process.stdout.write(envPaths('llxprt-code',{suffix:''}).config)")}/sandboxes"
ls "$SANDBOX_DIR"
cat "$SANDBOX_DIR/dev.json"
# Windows (PowerShell)
$ConfigHome = if ($env:LLXPRT_CONFIG_HOME) { $env:LLXPRT_CONFIG_HOME } `
  else { Join-Path $env:APPDATA 'llxprt-code\Config' }
$SANDBOX_DIR = Join-Path $ConfigHome 'sandboxes'
Get-ChildItem $SANDBOX_DIR
Get-Content "$SANDBOX_DIR\dev.json"

Common issues

Profile not found

If --sandbox-profile-load custom fails, verify the file exists:

SANDBOX_DIR="${LLXPRT_CONFIG_HOME:-$(node --input-type=module -e "import envPaths from 'env-paths'; process.stdout.write(envPaths('llxprt-code',{suffix:''}).config)")}/sandboxes"
ls "$SANDBOX_DIR/custom.json"

Invalid JSON

SANDBOX_DIR="${LLXPRT_CONFIG_HOME:-$(node --input-type=module -e "import envPaths from 'env-paths'; process.stdout.write(envPaths('llxprt-code',{suffix:''}).config)")}/sandboxes"
jq . "$SANDBOX_DIR/custom.json"

Engine missing

which docker
which podman

Related docs