๐Ÿ›ก๏ธ ZeptoCapsule

April 11, 2026 ยท View on GitHub

๐Ÿ›ก๏ธ ZeptoCapsule

Isolation sandbox for AI agents โ€” process, namespace, and Firecracker capsules.

License: Apache 2.0 Rust Linux macOS

3 isolation levels ยท automatic fallback ยท host capability probing ยท zero-config on macOS

Quick Start ยท Backends ยท Security Profiles ยท API


๐Ÿ“– Why Not Just Docker?

Docker is built for long-running services. AI agents are short-lived jobs โ€” spin up, call an LLM API, write an artifact, die. Each one takes ~7 MB of memory and finishes in seconds.

ApproachStartupOverheadIsolation
Docker container~1-2sImage layers, networking stack, storage driverGood
Firecracker microVM~125msFull guest kernel, ext4 rootfsExcellent
Linux namespace~5msKernel namespaces + cgroups, no runtimeGood
Plain fork()~1msNear-zeroMinimal

The right answer depends on the workload. An agent calling GPT-4 doesn't need a microVM. An agent running untrusted code does.

ZeptoCapsule gives you all three behind one API โ€” and automatically falls back when the host doesn't support a level.


โœจ Features

๐Ÿ”’ Three isolation backends โ€” process, namespace, Firecracker

๐Ÿ” Host capability probing โ€” auto-detects what your system supports

โฌ‡๏ธ Automatic fallback โ€” degrades gracefully (Firecracker โ†’ namespace โ†’ process)

๐Ÿ›ก๏ธ Security profiles โ€” Dev, Standard, Hardened

โฑ๏ธ Resource limits โ€” memory, CPU, PIDs, wall-clock timeout

๐Ÿ“ Workspace mounting โ€” host dir โ†” guest dir, artifact collection

๐Ÿ”ง Init shim โ€” zk-init binary bootstraps guest environments

๐Ÿ“Š Capsule reports โ€” exit code, peak memory, wall time, kill reason


๐Ÿ“ฆ Install

ZeptoCapsule is a library crate. Add it as a dependency:

[dependencies]
zeptocapsule = { path = "../zeptocapsule" }

Or build and run tests directly:

git clone https://github.com/qhkm/zeptocapsule.git
cd zeptocapsule
cargo test

๐Ÿš€ Quick Start

use zeptocapsule::{create, CapsuleSpec, Isolation, ResourceLimits, WorkspaceConfig, SecurityProfile};
use std::collections::HashMap;

#[tokio::main]
async fn main() {
    // Create a capsule
    let spec = CapsuleSpec {
        isolation: Isolation::Process,
        security: SecurityProfile::Dev,
        limits: ResourceLimits {
            timeout_sec: 30,
            memory_mib: Some(512),
            cpu_quota: None,
            max_pids: None,
        },
        workspace: WorkspaceConfig {
            host_path: Some("/tmp/my-workspace".into()),
            guest_path: "/workspace".into(),
            size_mib: None,
        },
        ..Default::default()
    };

    let mut capsule = create(spec).unwrap();

    // Spawn a worker process inside the capsule
    let child = capsule.spawn(
        "/usr/bin/echo",
        &["hello from capsule"],
        HashMap::new(),
    ).unwrap();

    // Read output, send input via child.stdout, child.stdin
    // ...

    // Tear down and get report
    let report = capsule.destroy().unwrap();
    println!("Exit: {:?}, Wall time: {:?}", report.exit_code, report.wall_time);
}

๐Ÿ”’ Isolation Backends

Process (Isolation::Process)

Plain fork() + setrlimit(). Works everywhere โ€” macOS, Linux, any Unix.

  • Wall-clock timeout via SIGKILL
  • Memory/CPU/file-size limits via setrlimit
  • No filesystem or network isolation
  • Best for: development, trusted agents, macOS

Namespace (Isolation::Namespace)

Linux user namespaces + cgroup v2. Container-level isolation without a container runtime.

  • CLONE_NEWUSER + CLONE_NEWPID + CLONE_NEWNS + CLONE_NEWIPC + CLONE_NEWUTS + CLONE_NEWNET
  • cgroup v2 enforcement: memory, CPU, PIDs
  • Init shim (zk-init) bootstraps the guest environment
  • Hardened mode adds pivot_root + seccomp-bpf
  • Best for: production Linux, untrusted prompts, resource enforcement

Firecracker (Isolation::Firecracker)

Full microVM via Firecracker. Strongest isolation โ€” separate kernel, separate address space.

  • KVM hardware acceleration
  • vsock (virtio sockets) for host โ†” guest stdio on ports 1001โ€“1004
  • ext4 workspace images โ€” seeded from host, exported back after teardown
  • Control channel for TERMINATE/KILL signals
  • Best for: untrusted code execution, hard security boundaries, multi-tenant

๐Ÿ›ก๏ธ Security Profiles

ProfileAvailable WithWhat It Adds
๐ŸŸข DevProcesssetrlimit + wall-clock timeout only
๐ŸŸก StandardNamespace, FirecrackerUser namespaces + cgroup limits + init shim
๐Ÿ”ด HardenedNamespace, FirecrackerStandard + pivot_root + seccomp-bpf whitelist

Seccomp Whitelist (Hardened)

Architecture-aware (x86_64 + aarch64). Only these syscall groups are allowed:

  • I/O: read, write, close, dup, pipe, poll, select
  • Memory: mmap, mprotect, brk, munmap
  • Process: clone, execve, exit, wait, getpid
  • Signals: rt_sigaction, rt_sigprocmask, kill
  • Filesystem: open, stat, access, getcwd, chdir
  • Socket: socket, connect, bind, listen, accept, sendto, recvfrom

Everything else โ†’ SIGSYS kill.


โฌ‡๏ธ Automatic Fallback

ZeptoCapsule probes host capabilities at runtime and degrades gracefully:

Firecracker requested โ†’ KVM available? โ†’ โœ… Use Firecracker
                                        โ†’ โŒ Try namespace
Namespace requested  โ†’ User NS + cgroup v2? โ†’ โœ… Use namespace
                                              โ†’ โŒ Fall back to process
Process requested    โ†’ Always works

Configure explicit fallback chains:

let spec = CapsuleSpec {
    isolation: Isolation::Firecracker,
    security: SecurityProfile::Hardened,
    fallback: Some(vec![
        (Isolation::Namespace, SecurityProfile::Hardened),
        (Isolation::Namespace, SecurityProfile::Standard),
        (Isolation::Process, SecurityProfile::Dev),
    ]),
    ..Default::default()
};

The CapsuleReport tells you what actually ran:

let report = capsule.destroy().unwrap();
println!("Requested: Firecracker/Hardened");
println!("Actual: {:?}/{:?}", report.actual_isolation, report.actual_security);

๐Ÿ” Host Probing

use zeptocapsule::probe;

let caps = probe();
println!("Arch: {:?}", caps.arch);
println!("User namespaces: {}", caps.user_namespaces);
println!("cgroup v2: {}", caps.cgroup_v2);
println!("Seccomp: {}", caps.seccomp_filter);
println!("KVM: {}", caps.kvm);
println!("Firecracker: {:?}", caps.firecracker_bin);

let (max_iso, max_sec) = caps.max_supported();
println!("Max supported: {:?}/{:?}", max_iso, max_sec);

๐Ÿ“– API Reference

Core

FunctionDescription
create(spec)Create a capsule from spec
capsule.spawn(bin, args, env)Spawn a process inside the capsule
capsule.kill(signal)Send Terminate or Kill signal
capsule.destroy()Tear down capsule, return CapsuleReport

Types

TypeDescription
CapsuleSpecIsolation level, limits, workspace, security profile
CapsuleChildSpawned process handle with stdin/stdout/stderr
CapsuleReportExit code, wall time, peak memory, kill reason
ResourceLimitsTimeout, memory, CPU quota, max PIDs
HostCapabilitiesDetected host features (KVM, namespaces, cgroups)

Errors

VariantWhen
SpawnFailedProcess/namespace/VM creation failed
Transportstdio or vsock communication error
CleanupFailedTeardown error (cgroup, workspace)
InvalidStateWrong lifecycle state (e.g., destroy before spawn)
NotSupportedRequested isolation not available on this host

๐Ÿ—๏ธ Architecture

ZeptoPM (orchestrator โ€” supervision, retries, job lifecycle)
    โ”‚
    โ”‚  create(spec) + spawn(worker, args, env)
    โ–ผ
ZeptoCapsule (sandbox โ€” isolation, resource enforcement, stdio transport)
    โ”‚
    โ”œโ”€โ”€ probe()          โ†’ detect host capabilities
    โ”œโ”€โ”€ create(spec)     โ†’ pick backend + apply fallback
    โ”‚
    โ”œโ”€โ”€ ProcessBackend   โ†’ fork() + setrlimit
    โ”œโ”€โ”€ NamespaceBackend โ†’ clone(NEWUSER|NEWPID|...) + cgroup v2
    โ””โ”€โ”€ FirecrackerBackend โ†’ microVM + vsock + ext4 workspace
         โ”‚
         โ”œโ”€โ”€ zk-init (guest) โ†’ bootstrap FS, exec worker
         โ”œโ”€โ”€ vsock 1001-1004 โ†’ stdin/stdout/stderr/control
         โ””โ”€โ”€ workspace.ext4  โ†’ seed from host, export back
              โ”‚
              โ–ผ
         ZeptoClaw (worker โ€” LLM calls, tool use, artifacts)
              โ”‚
              โ””โ”€โ”€ JSON-line IPC over stdin/stdout back to ZeptoPM

Stack responsibilities:

LayerOwnsDoes NOT own
ZeptoPMJob lifecycle, retries, supervision, event routingIsolation mechanisms
ZeptoCapsuleCapsule creation, process isolation, resource limits, stdio transportWorker protocol, job meaning
ZeptoClawLLM API calls, tool execution, artifact productionSandbox setup, resource enforcement

๐Ÿงฉ Zepto Stack

ZeptoCapsule is part of the Zepto stack โ€” a modular system for running AI agents in production.

LayerRepoRole
ZeptoPMqhkm/zeptopmProcess manager โ€” config-driven daemon, HTTP API, pipelines, orchestration
ZeptoCapsuleqhkm/zeptocapsuleSandbox โ€” process/namespace/Firecracker isolation, resource limits, fallback chains
ZeptoRTqhkm/zeptortDurable runtime โ€” journaled effects, snapshot recovery, OTP-style supervision
ZeptoClawqhkm/zeptoclawAgent framework โ€” 32 tools, 9 providers, 9 channels, container isolation

๐Ÿค Contributing

# Run tests (process backend โ€” works everywhere)
cargo test

# Run namespace tests (Linux only, needs privileges)
ZK_RUN_NAMESPACE_TESTS=1 cargo test

# Check Linux compilation from macOS
cargo check --target x86_64-unknown-linux-gnu

๐Ÿ“„ License

Apache 2.0

Made with ๐Ÿฆ€ by Aisar Labs

For commercial licensing, enterprise support, or managed hosting inquiries: qaiyyum@aisar.ai