Sandbox and Isolation Platform Research

Sandbox and Isolation Platform Research

Research Date: 2026-01-24 Researcher: Claude Code (Technical Research Agent) Objective: Analyze modern agentic and compute platforms to inform the design of agentic-sandbox's hybrid Docker+QEMU abstraction layer

Executive Summary

This research examines five leading platforms for workload isolation and sandboxing: Fly.io Machines, Modal, E2B, Daytona, and Firecracker. The analysis reveals a clear trend toward microVM-based isolation (Firecracker) for production agentic workloads, with container-based solutions for lighter-weight scenarios.

Key Findings:

1. Firecracker microVMs are the de facto standard for production isolation (used by Fly.io, AWS Lambda, Fargate) 2. Sub-second startup times are achievable with microVMs (125-150ms for Firecracker, 90ms for container-based solutions) 3. RESTful APIs dominate lifecycle management across all platforms 4. Network isolation by default with explicit opt-in for external access 5. Declarative configuration over imperative management 6. Resource limits enforced at hypervisor/kernel level, not trust-based

Recommendation: Implement a Firecracker-first approach for agentic-sandbox, with Docker fallback for development workflows. Abstract runtime selection behind a unified API.


Platform Analysis

1. Fly.io Machines

Purpose: Global edge computing platform for containerized applications

Runtime Isolation

AspectDetails
TechnologyFirecracker microVMs
Isolation LevelHardware virtualization (KVM-based)
Boot TimeSub-second (<1s typical)
DensityThousands of VMs per host
Memory Overhead<5 MiB per VM

Network Isolation

  • Default posture: Machines are closed to public internet
  • Service definitions: Explicit TCP/UDP port mappings required
  • Routing: Fly Proxy for HTTP/HTTPS traffic
  • Private networking: WireGuard mesh between Machines
  • External access: Requires service configuration with protocol handlers

Lifecycle Management API

REST API Endpoints:

# Create Machine
POST /v1/apps/{app_name}/machines
{
  "config": {
    "image": "registry.fly.io/my-app:latest",
    "guest": {
      "cpu_kind": "shared",
      "cpus": 1,
      "memory_mb": 256
    }
  }
}

# Start Machine
POST /v1/apps/{app_name}/machines/{machine_id}/start

# Stop Machine
POST /v1/apps/{app_name}/machines/{machine_id}/stop

# Suspend (pause and snapshot)
POST /v1/apps/{app_name}/machines/{machine_id}/suspend

# Delete Machine
DELETE /v1/apps/{app_name}/machines/{machine_id}

# Wait for state transition
GET /v1/apps/{app_name}/machines/{machine_id}/wait?state=started&timeout=30

# Get Machine details
GET /v1/apps/{app_name}/machines/{machine_id}

# Exec into Machine (via flyctl)
flyctl ssh console -a {app_name} -s

Key Features:

  • Leasing system: Nonce-based exclusive locks for concurrent access control
  • Cordoning: Temporarily remove from load balancing without deletion
  • Metadata: Custom key-value tagging
  • Auto-scaling: Event-driven on request arrival or resource pressure

Resource Limiting

{
  "guest": {
    "cpu_kind": "shared | performance",
    "cpus": 1,
    "memory_mb": 256,
    "gpu_kind": "a100-pcie-40gb | a100-sxm4-80gb | l40s"
  },
  "services": [{
    "protocol": "tcp",
    "internal_port": 8080,
    "ports": [{ "port": 80 }]
  }],
  "mounts": [{
    "volume": "data_volume",
    "path": "/data",
    "size_gb": 10,
    "size_gb_limit": 100
  }]
}
  • CPU: Shared (burstable) or performance (dedicated) cores
  • Memory: 256MB increments, minimum 256MB
  • Disk: Persistent volumes with auto-expansion thresholds
  • GPU: Optional passthrough for A100/L40S

External Service Access

  • Volumes: Persistent storage mounted at specified paths
  • Environment variables: Secrets management integration
  • DNS: Custom DNS resolution in private network
  • Outbound networking: Allowed by default when services configured

Strengths:

  • Production-grade microVM isolation
  • Global edge deployment
  • Sub-second cold starts
  • Strong API ergonomics
  • Built-in scaling primitives

Weaknesses:

  • Requires Fly.io account/platform
  • Limited to Firecracker (no alternative runtimes)
  • Network configuration can be complex

2. Modal

Purpose: Serverless compute platform for data/ML workloads and AI code execution

Runtime Isolation

AspectDetails
TechnologyContainers (implementation details proprietary)
Isolation LevelContainer-based (likely gVisor or similar)
Boot TimeSub-second (specific metrics not public)
ParadigmFunction-as-a-Service (FaaS) with Sandbox API

Network Isolation

  • Tunnels: TCP tunnel support for external connectivity
  • Cloud bucket mounts: S3-compatible storage access
  • Custom images: Full control over network tools in container

Lifecycle Management API

Python SDK:

from modal import Sandbox, Image

# Create sandbox
sandbox = Sandbox.create(
    image=Image.debian_slim().pip_install("numpy"),
    timeout=3600,           # Max 24 hours
    idle_timeout=300,       # Auto-terminate after 5min idle
    workdir="/workspace",
    encrypted=True
)

# Execute code
process = sandbox.exec("python", "script.py")
stdout = process.stdout.read()

# Filesystem operations
sandbox.write_file("/data/input.txt", "content")
content = sandbox.read_file("/data/output.txt")

# Terminate
sandbox.delete()

Named Sandboxes (for deployed apps):

# Create persistent named sandbox
sandbox = Sandbox.create(
    name="agent-1",  # Alphanumeric, dashes, dots, underscores; <64 chars
    image=custom_image,
    metadata={"project": "agent-system", "env": "prod"}
)

# Retrieve by name
sandbox = Sandbox.from_name("agent-1")

# List with filters
sandboxes = Sandbox.list(metadata={"project": "agent-system"})

Resource Limiting

sandbox = Sandbox.create(
    image=Image.debian_slim()
        .pip_install("pandas", "torch")
        .apt_install("ffmpeg"),
    timeout=86400,          # 24 hours max
    idle_timeout=600,       # 10 minutes
    encrypted=True,
    volumes={"/data": volume},
    secrets=[db_credentials],
    gpu="any"  # GPU acceleration
)
  • Timeout: Default 5 minutes, configurable up to 24 hours
  • Idle timeout: Automatic termination on inactivity
  • Activity detection: Active exec, stdin writes, TCP tunnel connections
  • Long-running: Use Filesystem Snapshots for state preservation >24h

External Service Access

  • Volumes: Persistent Modal volumes mounted to paths
  • Cloud buckets: S3/GCS/Azure blob storage mounts
  • Secrets: Environment variables from secure vault
  • Tunnels: TCP tunnels for database/service connections
  • Custom images: Package arbitrary dependencies

Strengths:

  • Excellent Python SDK ergonomics
  • Dynamic image creation (LLM-generated containers)
  • Built-in secrets management
  • Strong support for ML/data workflows
  • Named sandboxes for persistent agents

Weaknesses:

  • Proprietary platform (vendor lock-in)
  • Container-based (weaker isolation than microVMs)
  • 24-hour hard limit on sandbox lifetime
  • Limited documentation on underlying tech

3. E2B (e2b.dev)

Purpose: Open-source sandbox infrastructure specifically for AI agents executing code

Runtime Isolation

AspectDetails
TechnologyContainerized VMs (implementation suggests Firecracker)
Isolation LevelmicroVM ("small isolated VM")
Boot Time~150ms startup
ParadigmAI code interpreter sandbox

Network Isolation

  • Details not documented in public materials
  • Assumed: Default isolation with opt-in external access

Lifecycle Management API

JavaScript/TypeScript SDK:

import { Sandbox } from '@e2b/code-interpreter'

// Create sandbox
const sbx = await Sandbox.create()

// Execute code
await sbx.runCode('x = 1')
const execution = await sbx.runCode('x += 1; x')
console.log(execution.text)  // "2"

// Filesystem operations
await sbx.filesystem.write('/tmp/data.txt', 'content')
const data = await sbx.filesystem.read('/tmp/data.txt')

// Close sandbox
await sbx.close()

Python SDK:

from e2b import Sandbox

# Create sandbox
sandbox = Sandbox()

# Execute code
result = sandbox.run_code("print('Hello from E2B')")
print(result.stdout)

# Filesystem
sandbox.filesystem.write("/workspace/code.py", "x = 1 + 1\
print(x)")
sandbox.run_code("exec(open('/workspace/code.py').read())")

# Cleanup
sandbox.close()

Resource Limiting

  • Not publicly documented in detail
  • Inferred from positioning: Lightweight, fast startup suggests resource efficiency

External Service Access

  • Not publicly documented
  • Infrastructure repository indicates self-hosting on GCP (production) and AWS (in development)

Self-Hosting:

# E2B can be self-hosted via Terraform
git clone https://github.com/e2b-dev/infra
cd infra
# Follow self-hosting guide (GCP production-ready, AWS in development)

Strengths:

  • Open-source: Self-hostable infrastructure
  • Purpose-built for AI agent code execution
  • Fast startup (~150ms)
  • Simple SDK for code interpreter pattern
  • Multi-language support (Python, JavaScript, others)

Weaknesses:

  • Limited public documentation on architecture
  • Self-hosting still immature (AWS support in progress)
  • Network/resource configuration unclear
  • Smaller ecosystem than commercial platforms

4. Daytona

Purpose: Development environment orchestration for cloud IDEs and agent sandboxes

Runtime Isolation

AspectDetails
TechnologyOCI/Docker containers
Isolation LevelContainer-based
Boot TimeSub-90ms startup
ParadigmDevelopment workspace sandboxes

Network Isolation

  • Egress limits: Network bandwidth constraints
  • Region selection: Geographic placement control
  • Custom infrastructure: Self-hosted options

Lifecycle Management API

Python SDK:

from daytona_sdk import Sandbox

# Create sandbox
sandbox = Sandbox.create(
    image="python:3.11-slim"
)

# Execute code
result = sandbox.code_run("print('Hello')")

# Cleanup
sandbox.delete()

TypeScript SDK:

import { Sandbox } from 'daytona-sdk'

const sandbox = await Sandbox.create({
  image: 'node:18'
})

await sandbox.codeRun('console.log("Hello")')
await sandbox.delete()

Additional APIs:

  • File API: Filesystem operations within sandbox
  • Git API: Repository cloning and operations
  • LSP API: Language Server Protocol for IDE features
  • Execute API: Command execution

Resource Limiting

  • Network: Egress bandwidth limits
  • Organizational quotas: Tier-based resource limits
  • Volume management: Persistent storage allocation
  • Billing-based: Resource consumption metering

External Service Access

  • Git repositories: SSH/HTTPS integration
  • Web terminals: Interactive browser-based access
  • SSH access: Direct SSH connections to sandboxes
  • Webhooks: Event notification system
  • Volumes: Persistent storage mounts

Strengths:

  • Extremely fast startup (<90ms)
  • Persistent sandboxes ("can live forever")
  • Multi-language SDK support
  • Git/LSP integration for development workflows
  • Web terminal and SSH access

Weaknesses:

  • Container-based isolation (weaker than microVMs)
  • Limited public architecture documentation
  • Resource limiting details unclear
  • Appears commercial/closed-source

5. Firecracker

Purpose: Foundational microVM technology for serverless and container workloads (AWS Lambda, Fargate, Fly.io)

Runtime Isolation

AspectDetails
TechnologyKVM-based microVMs in userspace
Isolation LevelHardware virtualization + process jail
Boot Time125ms to user code
Density150 microVMs/sec/host creation rate
Memory Overhead<5 MiB per microVM

Key Differentiator from Containers:

Firecracker combines hardware virtualization security (separate kernel per VM) with container-like speed and efficiency. Unlike containers that share the host kernel, each microVM runs its own kernel instance, providing stronger isolation.

Architecture

┌────────────────────────────────────────┐
│          Host Linux Kernel              │
│              (KVM enabled)              │
└────────────┬───────────────────────────┘
             │
    ┌────────┴─────────┐
    │  Firecracker VMM │  (Rust userspace process)
    │   (REST API)     │
    └────────┬─────────┘
             │
    ┌────────┴──────────────────────────┐
    │         Jailer Process             │
    │  (cgroup/namespace isolation)      │
    │  (privilege dropping)              │
    └────────┬──────────────────────────┘
             │
    ┌────────┴─────────┐
    │    microVM       │
    │  ┌────────────┐  │
    │  │ Guest OS   │  │
    │  │ (kernel)   │  │
    │  └────────────┘  │
    └──────────────────┘

Minimalist Device Model:

Only 5 emulated devices to reduce attack surface:

  • `virtio-net` - Network interface
  • `virtio-block` - Block storage
  • `virtio-vsock` - VM socket communication
  • Serial console
  • Minimal keyboard controller (i8042)

Network Isolation

# Add network interface
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/network-interfaces/eth0' \
  -d '{
    "iface_id": "eth0",
    "guest_mac": "AA:FC:00:00:00:01",
    "host_dev_name": "tap0"
  }'
  • Tap devices: Network interfaces connected to host tap devices
  • Rate limiters: Built-in bandwidth and IOPS throttling
  • No default networking: Explicit configuration required

Lifecycle Management API

RESTful API (Unix socket):

# Configure machine resources
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/machine-config' \
  -d '{
    "vcpu_count": 2,
    "mem_size_mib": 512,
    "ht_enabled": false,
    "track_dirty_pages": false
  }'

# Set kernel and rootfs
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/boot-source' \
  -d '{
    "kernel_image_path": "/path/to/vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1"
  }'

curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/drives/rootfs' \
  -d '{
    "drive_id": "rootfs",
    "path_on_host": "/path/to/rootfs.ext4",
    "is_root_device": true,
    "is_read_only": false
  }'

# Start VM
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/actions' \
  -d '{ "action_type": "InstanceStart" }'

# Graceful shutdown (x86_64 only)
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/actions' \
  -d '{ "action_type": "SendCtrlAltDel" }'

# Flush metrics
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/actions' \
  -d '{ "action_type": "FlushMetrics" }'

Production Deployment (with Jailer):

# Jailer provides security isolation
./jailer \
  --id unique-vm-id \
  --uid 123 \
  --gid 100 \
  --chroot-base-dir /srv/firecracker \
  --exec-file /usr/bin/firecracker \
  --netns /var/run/netns/my-netns \
  --daemonize

Resource Limiting

vCPU and Memory:

{
  "vcpu_count": 2,
  "mem_size_mib": 512,
  "ht_enabled": false,
  "cpu_template": "C3"  // Intel-specific CPU features
}

I/O Rate Limiting:

{
  "drive_id": "rootfs",
  "path_on_host": "/path/to/rootfs.ext4",
  "rate_limiter": {
    "bandwidth": {
      "size": 10485760,      // 10 MiB/s
      "refill_time": 1000    // ms
    },
    "ops": {
      "size": 1000,          // IOPS
      "refill_time": 1000
    }
  }
}

Network Rate Limiting:

{
  "iface_id": "eth0",
  "rx_rate_limiter": {
    "bandwidth": { "size": 52428800, "refill_time": 1000 },  // 50 MiB/s
    "ops": { "size": 10000, "refill_time": 1000 }
  },
  "tx_rate_limiter": {
    "bandwidth": { "size": 52428800, "refill_time": 1000 },
    "ops": { "size": 10000, "refill_time": 1000 }
  }
}

External Service Access

  • Network interfaces: Tap devices for L2 connectivity
  • Vsock: VM socket for host-guest communication
  • Block devices: Multiple drives mountable
  • Metadata service: Secure config sharing between host and guest
  • Serial console: Out-of-band access

Strengths:

  • Industry-standard: Powers AWS Lambda, Fargate, Fly.io
  • Maximum security: Hardware virtualization + minimal attack surface
  • Lightning-fast: 125ms boot to userspace
  • Resource efficient: <5 MiB overhead per VM
  • Production-proven: Billions of production workloads
  • Open-source: Apache 2.0 license
  • Fine-grained control: Granular rate limiting and resource management

Weaknesses:

  • Requires KVM: Linux-only, bare metal or .metal instances
  • Low-level API: More complex than PaaS abstractions
  • Manual networking: No built-in service mesh
  • Kernel/rootfs management: Must provide guest OS images

Comparison Matrix

Runtime Isolation Technology

PlatformTechnologyIsolation LevelBoot TimeMemory Overhead
Fly.ioFirecracker microVMsHardware (KVM)<1s<5 MiB/VM
ModalContainers (proprietary)OS (container)<1sUnknown
E2BContainerized VMs (likely Firecracker)Hardware (microVM)~150msUnknown
DaytonaOCI/Docker containersOS (container)<90msStandard container
FirecrackerKVM microVMsHardware (KVM)125ms<5 MiB/VM

Lifecycle Management API

PlatformProtocolKey OperationsAuthentication
Fly.ioREST (HTTPS)create, start, stop, suspend, delete, wait, execAPI token
ModalPython/TypeScript SDKcreate, exec, read_file, write_file, deleteAPI key
E2BPython/JavaScript SDKcreate, runCode, filesystem ops, closeAPI key
DaytonaPython/TypeScript SDKcreate, code_run, delete, git/lsp opsAPI key
FirecrackerREST (Unix socket)configure, start, stop, rate_limitLocal socket

Network Isolation

PlatformDefault PostureExternal Access MethodRate Limiting
Fly.ioClosedService definitions + Fly ProxyYes (via config)
ModalIsolatedTunnels, cloud mounts, custom imagesUnknown
E2BIsolated (assumed)Not documentedUnknown
DaytonaIsolatedSSH, webhooks, git integrationEgress limits
FirecrackerNone by defaultTap devices (manual setup)Yes (built-in)

Resource Limiting

PlatformCPUMemoryDiskGPUTimeout
Fly.ioShared/Performance cores256MB+ (256MB increments)Volume size + auto-expandA100, L40SN/A (persistent)
ModalConfigurableConfigurableVolumes"any"5min-24h
E2BNot documentedNot documentedNot documentedUnknownUnknown
DaytonaQuota-basedQuota-basedVolumesUnknownNone ("live forever")
FirecrackervCPU countMiB configRate-limited I/OPassthroughN/A (manual)

External Service Access

PlatformStorageSecretsNetworkingGitOther
Fly.ioVolumesENV varsPrivate WireGuard meshVia shellMetadata KV
ModalVolumes, cloud bucketsSecrets APITunnelsNot built-inLSP support
E2BFilesystem APINot documentedNot documentedCookbook examplesCode interpreter focus
DaytonaVolumesNot documentedSSH, webhooksGit APILSP, web terminal
FirecrackerBlock devicesN/A (guest handles)Tap devices, vsockN/AMetadata service

1. Runtime Abstraction Layer

Implement a unified API that abstracts Docker and QEMU (Firecracker) runtimes:

# Unified agent specification
apiVersion: v1
kind: AgentSandbox
metadata:
  name: agent-claude-001
  labels:
    project: migration-automation
    isolation: high
spec:
  runtime:
    type: firecracker  # or: docker, qemu
    preference: firecracker-preferred  # Fallback to docker if unavailable

  resources:
    vcpu: 2
    memory: 2G
    disk: 10G
    gpu: false

  image:
    source: registry.local/agent-claude:latest
    kernel: /images/kernels/vmlinux-5.10  # For microVM runtimes
    rootfs: /images/rootfs/ubuntu-22.04.ext4

  network:
    mode: isolated  # isolated, bridge, host
    egress:
      allowInternet: false
      allowedHosts:
        - github.com
        - api.anthropic.com
    ingress: []

  storage:
    volumes:
      - name: workspace
        path: /workspace
        size: 5G
        mode: rw
      - name: cache
        path: /cache
        size: 1G
        mode: rw

  lifecycle:
    timeout: 86400  # 24 hours
    idleTimeout: 3600  # 1 hour
    onExit: cleanup  # cleanup, preserve

  integrations:
    - type: git
      credentials: ssh-key-secret
    - type: s3
      endpoint: s3.local:9000
      bucket: agent-artifacts

2. Firecracker-First Architecture

Decision Matrix:

┌─────────────────────────────────────────────────────────┐
│              Agent Sandbox Request                       │
└─────────────┬───────────────────────────────────────────┘
              │
              ▼
    ┌─────────────────────┐
    │   Is KVM available?  │
    └─────────┬───────────┘
              │
         Yes  │  No
         ┌────┴────┐
         ▼         ▼
    ┌────────┐  ┌─────────┐
    │Security│  │Fast dev │
    │ high?  │  │startup? │
    └────┬───┘  └────┬────┘
         │           │
    Yes  │  No  Yes  │  No
    ┌────┴────┐ ┌───┴────┐
    ▼         ▼ ▼        ▼
┌────────┐ ┌───────┐ ┌────────┐ ┌──────┐
│Firecrk.│ │Docker │ │Docker  │ │QEMU  │
│microVM │ │+seccomp│ │minimal │ │full  │
│        │ │       │ │        │ │ VM   │
└────────┘ └───────┘ └────────┘ └──────┘
  125ms     <1s       <1s       5-10s
  Max       High      Medium    Max
  isolation isolation isolation isolation

Implementation Priority:

1. Phase 1: Docker runtime with hardened security profiles (immediate) 2. Phase 2: Firecracker microVM runtime (recommended for production) 3. Phase 3: QEMU full VM runtime (for GPU passthrough, special hardware)

3. API Design (RESTful + SDK)

REST API (inspired by Fly.io Machines API):

# Create sandbox
POST /api/v1/sandboxes
{
  "name": "agent-001",
  "spec": { ... }  # YAML spec from above
}
Response: 201 Created
{
  "id": "sb_abc123",
  "name": "agent-001",
  "state": "creating",
  "runtime": "firecracker",
  "created_at": "2026-01-24T10:00:00Z"
}

# Start sandbox
POST /api/v1/sandboxes/{id}/start
Response: 200 OK

# Execute command
POST /api/v1/sandboxes/{id}/exec
{
  "command": ["python", "script.py"],
  "stdin": "input data",
  "env": {"VAR": "value"}
}
Response: 200 OK
{
  "stdout": "...",
  "stderr": "...",
  "exit_code": 0
}

# Get logs
GET /api/v1/sandboxes/{id}/logs?since=1h&follow=true
Response: 200 OK (streaming)

# Stop sandbox
POST /api/v1/sandboxes/{id}/stop
Response: 200 OK

# Delete sandbox
DELETE /api/v1/sandboxes/{id}
Response: 204 No Content

# Wait for state
GET /api/v1/sandboxes/{id}/wait?state=running&timeout=30
Response: 200 OK
{
  "state": "running",
  "ready": true
}

Python SDK (inspired by Modal/E2B):

from agentic_sandbox import Sandbox, Image, Volume

# Create sandbox
sandbox = Sandbox.create(
    name="agent-001",
    image=Image.ubuntu("22.04")
        .apt_install("python3", "git")
        .pip_install("anthropic"),
    runtime="firecracker-preferred",  # Fallback to docker
    resources={
        "vcpu": 2,
        "memory": "2G",
        "disk": "10G"
    },
    network={
        "mode": "isolated",
        "egress": {
            "allow_internet": False,
            "allowed_hosts": ["github.com"]
        }
    },
    volumes={
        "/workspace": Volume.create(size="5G", mode="rw")
    },
    timeout=86400,
    idle_timeout=3600
)

# Wait for ready
sandbox.wait(state="running", timeout=30)

# Execute commands
result = sandbox.exec("git", "clone", "https://github.com/user/repo")
print(result.stdout)

# Filesystem operations
sandbox.write_file("/workspace/config.json", json.dumps(config))
output = sandbox.read_file("/workspace/output.txt")

# Stream logs
for line in sandbox.logs(follow=True):
    print(line)

# Cleanup
sandbox.delete()

4. Security Hardening

Docker Runtime Security:

# runtimes/docker/seccomp-agent.json
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_AARCH64"],
  "syscalls": [
    {
      "names": [
        "read", "write", "open", "close", "stat", "fstat",
        "lstat", "poll", "lseek", "mmap", "mprotect", "munmap",
        "brk", "rt_sigaction", "rt_sigprocmask", "ioctl", "access",
        "execve", "exit", "wait4", "clone", "fork", "vfork"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}
# docker-compose.yml
services:
  agent-sandbox:
    image: agent-base
    security_opt:
      - no-new-privileges:true
      - seccomp=seccomp-agent.json
      - apparmor=agent-profile
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # Only if needed
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=1G
      - /var/tmp:noexec,nosuid,size=1G
    networks:
      - isolated
    dns:
      - 1.1.1.1
      - 1.0.0.1
    sysctls:
      - net.ipv4.ip_forward=0
      - net.ipv6.conf.all.disable_ipv6=1

Firecracker Runtime Security:

# Production jailer configuration
./jailer \
  --id agent-001 \
  --uid 1000 \
  --gid 1000 \
  --chroot-base-dir /srv/firecracker/vms \
  --exec-file /usr/bin/firecracker \
  --netns /var/run/netns/agent-net \
  --daemonize \
  --cgroup cpu:agent-001:/sys/fs/cgroup/cpu/agent-001 \
  --cgroup mem:agent-001:/sys/fs/cgroup/memory/agent-001

5. Parent-Child Agent Patterns

Hierarchical Agent Spawning:

# Parent agent spawns child agents for subtasks
from agentic_sandbox import Sandbox, AgentPool

class ParentAgent:
    def __init__(self):
        self.pool = AgentPool(max_concurrent=5)

    def spawn_child_agent(self, task):
        """Spawn isolated child agent for subtask"""
        child = Sandbox.create(
            name=f"child-{task.id}",
            image=Image.from_parent(inherit_tools=True),
            runtime="firecracker",
            resources={
                "vcpu": 1,
                "memory": "1G",
                "disk": "5G"
            },
            network={
                "mode": "isolated",
                "egress": {
                    "allow_internet": False,
                    "allowed_hosts": task.required_hosts
                }
            },
            timeout=3600,
            lifecycle={
                "on_exit": "cleanup",
                "parent_id": self.sandbox_id
            }
        )

        return child

    def coordinate_subtasks(self, task):
        """Parallel execution with child agents"""
        subtasks = self.decompose_task(task)

        # Spawn children
        children = [
            self.pool.submit(self.spawn_child_agent, st)
            for st in subtasks
        ]

        # Collect results
        results = [child.wait_for_completion() for child in children]

        # Cleanup
        for child in children:
            child.delete()

        return self.aggregate_results(results)

Message-Based Coordination:

# Parent-child coordination via message queue
from agentic_sandbox import Sandbox, MessageQueue

parent = Sandbox.create(
    name="parent-agent",
    integrations=[
        {"type": "nats", "endpoint": "nats://queue:4222"}
    ]
)

child = Sandbox.create(
    name="child-agent",
    integrations=[
        {"type": "nats", "endpoint": "nats://queue:4222"}
    ]
)

# Parent publishes tasks
queue = MessageQueue.connect("nats://queue:4222")
queue.publish("tasks.subtask1", {"action": "analyze", "data": "..."})

# Child subscribes and processes
child.exec("python", "worker.py", "--subscribe=tasks.*")

6. Integration Bridges

Git Bridge (SSH proxy):

# Integration bridge for Git access
services:
  git-bridge:
    image: git-ssh-proxy
    volumes:
      - ./ssh-keys:/keys:ro
    environment:
      ALLOWED_REPOS: "github.com/org/*,gitlab.com/org/*"
    networks:
      - agent-network
    security_opt:
      - no-new-privileges:true

S3 Bridge (MinIO proxy):

services:
  s3-bridge:
    image: minio/minio
    command: server /data --console-address ":9001"
    volumes:
      - ./artifacts:/data
    networks:
      - agent-network
    environment:
      MINIO_ROOT_USER: agent
      MINIO_ROOT_PASSWORD: ${S3_PASSWORD}

7. Monitoring and Observability

# Prometheus metrics endpoint
GET /metrics
# HELP sandbox_count Number of active sandboxes
# TYPE sandbox_count gauge
sandbox_count{runtime="firecracker"} 5
sandbox_count{runtime="docker"} 12

# HELP sandbox_cpu_usage CPU usage per sandbox
# TYPE sandbox_cpu_usage gauge
sandbox_cpu_usage{id="sb_001",runtime="firecracker"} 0.45

# HELP sandbox_memory_bytes Memory usage in bytes
# TYPE sandbox_memory_bytes gauge
sandbox_memory_bytes{id="sb_001",runtime="firecracker"} 524288000

# HELP sandbox_lifetime_seconds Sandbox uptime
# TYPE sandbox_lifetime_seconds gauge
sandbox_lifetime_seconds{id="sb_001",runtime="firecracker"} 3600

Claude Code Agent Spawning Patterns

Note: Research on Claude Code's `--dangerously-skip-permissions` flag was inconclusive from public documentation. However, based on analysis of similar agent systems, recommended patterns include:

Pattern 1: Nested Agent Execution

# Parent Claude Code instance spawns child in isolated sandbox
claude-code --sandbox firecracker \
  --command "claude-code --agent-mode autonomous --task 'analyze codebase'"

Pattern 2: API-Based Spawning

# Parent agent uses SDK to spawn child sandbox
from anthropic import Anthropic
from agentic_sandbox import Sandbox

client = Anthropic()

# Create isolated child sandbox
child = Sandbox.create(
    name="child-analyzer",
    image=Image.claude_code(),
    runtime="firecracker",
    timeout=3600
)

# Inject task via environment
child.env["CLAUDE_TASK"] = "Analyze the codebase and identify security issues"
child.env["CLAUDE_API_KEY"] = parent_api_key

# Start Claude Code in child
child.exec("claude-code", "--agent-mode", "autonomous")

# Monitor progress
for log in child.logs(follow=True):
    if "TASK_COMPLETE" in log:
        break

results = child.read_file("/workspace/analysis.md")
child.delete()

Pattern 3: Capability-Based Isolation

# Different capability profiles for different agent roles
agents:
  - name: coordinator
    capabilities:
      - spawn_children
      - read_results
      - network_internal

  - name: code_analyzer
    capabilities:
      - read_code
      - write_reports
      - no_network

  - name: deployment_agent
    capabilities:
      - read_configs
      - write_artifacts
      - network_external
      - access_k8s

Implementation Roadmap

Phase 1: Foundation (Weeks 1-2)

  • [ ] Implement YAML agent specification parser
  • [ ] Build Docker runtime adapter with seccomp profiles
  • [ ] Create REST API server (start, stop, exec, logs, delete)
  • [ ] Implement basic resource limiting (CPU, memory via cgroups)
  • [ ] Add network isolation (bridge mode with iptables rules)

Phase 2: Firecracker Integration (Weeks 3-4)

  • [ ] Build Firecracker runtime adapter
  • [ ] Implement kernel/rootfs image management
  • [ ] Add Firecracker jailer integration
  • [ ] Create microVM lifecycle manager
  • [ ] Implement vsock for host-guest communication
  • [ ] Add Firecracker rate limiting configuration

Phase 3: Advanced Features (Weeks 5-6)

  • [ ] Build Python SDK (create, exec, logs, delete)
  • [ ] Implement volume management
  • [ ] Add integration bridges (Git, S3)
  • [ ] Create parent-child agent coordination
  • [ ] Add metrics and observability (Prometheus)
  • [ ] Implement agent pools for concurrent execution

Phase 4: Production Hardening (Weeks 7-8)

  • [ ] Add comprehensive error handling
  • [ ] Implement retry logic and fault tolerance
  • [ ] Create audit logging system
  • [ ] Add resource quota enforcement
  • [ ] Build health check and auto-recovery
  • [ ] Performance testing and optimization

Conclusion

Modern agentic platforms have converged on Firecracker microVMs for production isolation, with container-based solutions for development and lighter workloads. The agentic-sandbox project should:

1. Prioritize Firecracker as the primary runtime for production agent workloads 2. Maintain Docker support for development, testing, and environments without KVM 3. Abstract runtime details behind a unified API (REST + SDK) 4. Implement defense-in-depth security (jailer, seccomp, capabilities, network isolation) 5. Support parent-child patterns for hierarchical agent coordination 6. Provide integration bridges for external services (Git, S3, message queues)

Next Steps:

1. Review this research with stakeholders 2. Finalize technical design document 3. Begin Phase 1 implementation (Docker runtime) 4. Prototype Firecracker integration (Phase 2) 5. Test with Claude Code agent spawning scenarios


References


Report Prepared By: Claude Code (Technical Research Agent) Date: 2026-01-24 Confidence Level: High Recommendation: Adopt Firecracker-first architecture with Docker fallback