Repository navigation
Sandboxing
Every command an agent runs passes four checks first (see Concepts and Architecture). The sandbox is the last line: it limits what an approved command can actually touch. The full reference is docs/reference/sandboxing.md.
If a sandbox cannot be applied (no Landlock in the kernel, a seccomp filter rejected, sandbox_init() failing on macOS, a Firecracker guest that produces no output), the action is aborted, not run unprotected on the host. ECTO_SANDBOX_PERMISSIVE=true switches to a logged warning and advisory checks only. Leave it unset outside development.
| Platform | Mechanism | Filesystem | Process | Resource limits |
|---|---|---|---|---|
| Linux | Landlock + seccomp-BPF + rlimits (build feature sandbox, on by default) |
Landlock, workspace read-only | seccomp syscall allowlist | rlimits: CPU, address space, file descriptors |
| macOS | Seatbelt (sandbox_init), applied to each child process |
Read and write in the workspace only |
process-exec allowed; commands limited by the tripwire and executable allowlist |
Not enforced |
| Windows | Job Objects with UI restrictions | No restriction beyond NTFS permissions | Cleanup guaranteed, no syscall filtering | Partial |
| Docker / Podman | A container per command | Read-only root | Container, --user nobody
|
cgroups |
| Firecracker | A microVM per command | Guest filesystem | KVM microVM | vCPU and memory |
Needs kernel 5.13 or newer with Landlock enabled. A kernel without Landlock is a sandbox failure, so the command is aborted. The rlimits cap a command at 30 seconds of CPU, 512 MiB of address space and 64 file descriptors. A seccomp filter that the kernel rejects stops serve; it does not continue unsandboxed.
The Seatbelt profile allows read access to system libraries, read and write in the workspace, stat (not listing) of the workspace's parent folders, and denies network and signals for child processes. Known limits:
-
/usr/bin/gitand other Xcode command-line shims do not run under the profile. Use a Homebrewgit(/opt/homebrew/bin) or run without the sandbox. -
ls ..from the workspace is refused;ls -lain the workspace works. - No resource limits. Only the child process loses network access, not IronVise itself.
- Apple has deprecated the public
sandbox_initheader; the enforcement is still active.
For production on macOS, use the Docker tier or run IronVise in a Linux container.
Job Objects guarantee child processes are cleaned up (KILL_ON_JOB_CLOSE) and block UI escalation such as clipboard access and display changes. They do not restrict file access or filter system calls. For production on Windows, use the Docker tier.
Works on every platform with Docker or Podman installed. Each run_command runs in a fresh container with --network=none, --read-only, --security-opt no-new-privileges, --user nobody, and --memory / --cpus limits.
export ECTO_DOCKER_IMAGE=alpine:3.19
export ECTO_DOCKER_RUNTIME=auto # auto, docker or podman
export ECTO_DOCKER_MEMORY=256m
export ECTO_DOCKER_CPUS=1
export ECTO_DOCKER_TIMEOUT=30This is the simplest way to get strong isolation with no guest image to build.
An optional isolation tier for Linux hosts with KVM: each run_command runs in an ephemeral microVM that is destroyed afterwards. It gives hardware-level isolation and is the strongest tier.
- Linux with KVM, and a build with the feature:
cargo build --release -p ectoledger --features sandbox,sandbox-firecracker - Firecracker 1.5 or newer
- A guest kernel (
vmlinux) and a root filesystem that implements the IronVise guest protocol (below)
export ECTO_FC_BINARY=/usr/local/bin/firecracker # setting this opts in
export ECTO_FC_KERNEL=/opt/ectoledger/vmlinux
export ECTO_FC_ROOTFS=/opt/ectoledger/rootfs.ext4
export ECTO_FC_VCPUS=1
export ECTO_FC_MEM_MIB=128
export ECTO_FC_TIMEOUT_SECS=30
ironvise audit "Your goal"scripts/provision-firecracker.sh --rootfs busyboxbuilds a minimal busybox root filesystem whose init implements the protocol. Without --rootfs busybox the script first tries the Firecracker project's official Ubuntu CI rootfs, which does not implement the protocol; it falls back to busybox only if that download fails. If an official rootfs is already installed, delete it and re-run with --rootfs busybox.
scripts/setup-firecracker.sh installs the Firecracker project's hello kernel and rootfs. That image is a plumbing test only (KVM, binary, kernel and block devices): it contains no IronVise guest agent and executes no intent.
A microVM with a rootfs that does not implement the protocol produces no output, and the action is aborted (fail-closed).
| Device | Contents |
|---|---|
/dev/vda |
Your rootfs, the root device |
/dev/vdb |
The intent as a raw JSON image (not a filesystem: read the device directly) |
/dev/ttyS0 |
Serial console; its output becomes the command's output on the host |
The guest init must:
- Read the raw bytes of
/dev/vdband strip trailing NUL padding. - Parse the JSON, handle
action == "run_command"and takeparams.command. Treat any other action as unsupported. - Run the command inside the guest.
- Write its stdout and stderr to
/dev/ttyS0. - Shut down (for example
reboot -f). The host appliesECTO_FC_TIMEOUT_SECSif the guest hangs.
An illustrative shell init and image-building notes are in the guest image contract. Use a real JSON parser in anything you deploy.
| Where | Setup |
|---|---|
| Linux production | Native sandbox (default build); add Firecracker or Docker for untrusted workloads |
| macOS production | Docker tier, or IronVise in a Linux container |
| Windows production | Docker tier |
| Development on any OS | ECTO_DOCKER_IMAGE=alpine:3.19 |
Separate from command sandboxing, three optional enclave runtimes can hold the guard model's inference inside a confidentiality boundary: Level 1 software-hardened (--features enclave), Level 2 Apple Hypervisor on Apple Silicon (--features sandbox-apple-enclave), and Level 3 remote hardware enclave with AWS Nitro attestation (--features enclave-remote). In 0.8 these runtimes are built and tested but not wired into the agent loop: no prompt is routed through an enclave. Details are in the sandboxing reference.
IronVise, by EctoSpace. Repository | Website | Releases | Report a vulnerability. The server is licensed under BUSL-1.1; the SDKs under Apache-2.0. Compliance mappings are aids, not legal advice or certification.
Get going
Understand
Use
Operate
Project