AI Agent Sandbox Blueprint is a production TEE sandbox runtime for AI agents on Tangle Network. It supports AWS Nitro, Azure, GCP, and Phala backends with sealed secrets, attestation, and managed Docker sandboxes for multi-tenant AI workloads.
A Tangle Network blueprint that provides managed Docker sandboxes for AI agents. Operators run sidecar containers and expose them through both on-chain jobs (lifecycle management) and an authenticated HTTP API (read/write operations like exec, prompt, SSH, secrets).
Three deployment modes:
- Sandbox (cloud): Multi-tenant fleet — callers create/delete sandboxes on-demand via on-chain jobs
- Instance: Single sandbox per service — auto-provisioned on operator startup
- TEE Instance: Same as instance but with TEE attestation and sealed secrets
Caller ─── Tangle EVM ─── BlueprintRunner ─── Job Handlers
│
Operator API (HTTP + PASETO auth)
│
Docker / Docktopus ─── Sidecar Containers
Canonical references:
docs/ARCHITECTURE.mddocs/CONTRACTS.mdBLUEPRINT_FACTORY_STATUS.md
Hard rules:
- On-chain jobs must mutate authoritative state. No read-only jobs.
- Read-only flows must use
eth_callor the off-chain operator HTTP API.
Layer boundaries:
microvm-blueprint= infrastructure layersandbox-runtime= runtime contracts/adapters layerai-agent-sandbox-blueprint,ai-trading-blueprints,openclaw-hosting-blueprint= product layer
Dependency direction:
- Allowed: Product ->
sandbox-runtime->microvm-blueprint - Forbidden: Product ->
microvm-blueprint(direct), product -> product
| Crate | Role |
|---|---|
sandbox-runtime |
Shared library: Docker lifecycle, operator API, session auth, rate limiting, metrics, encryption, and L1 contracts (SandboxProvider/RuntimeAdapter) |
ai-agent-sandbox-blueprint-lib |
Cloud/sandbox mode job handlers + workflows |
ai-agent-instance-blueprint-lib |
Instance mode: auto-provision + billing |
ai-agent-tee-instance-blueprint-lib |
TEE instance: attestation + sealed secrets |
*-bin |
Binary entry points (one per mode) |
contracts/ |
Solidity BSM contract (deployed 3x with different flags) |
ui/ |
React frontend for sandbox management |
The UI uses two shared packages. Keep responsibilities strict to avoid copy/paste drift:
@tangle-network/blueprint-ui:- Blueprint and chain infrastructure (
publicClient, chain/address helpers, ABI exports) - Job/provisioning/quote utilities, infra/session/tx stores
- Reusable cross-blueprint UI primitives and layout components
- npm: https://www.npmjs.com/package/@tangle-network/blueprint-ui
- Blueprint and chain infrastructure (
@tangle-network/agent-ui:- Agent chat/session rendering, run/tool timeline UI, markdown/tool previews
- Sidecar auth/session hooks and PTY terminal integration
- Shared lightweight UI utilities in
@tangle-network/agent-ui/primitives - Published from this repo via
.github/workflows/publish-agent-ui.yml - npm: https://www.npmjs.com/package/@tangle-network/agent-ui
- App-local (
ui/src/**):- Sandbox-specific routes, workflows, feature copy, and product behavior
- Sandbox-only shell/layout styling concerns
Extraction rule:
- If Sandbox UI and Arena UI carry the same non-trivial implementation (roughly 20+ lines), promote it to the appropriate shared package instead of creating a third copy.
- Recommended duplication check:
npx jscpd --min-lines 8 --min-tokens 80 --format ts,tsx --ignore "**/node_modules/**,**/.next/**,**/dist/**,**/build/**" /home/drew/code/blueprint-ui/src /home/drew/code/ai-agent-sandbox-blueprint/packages/agent-ui/src /home/drew/code/ai-agent-sandbox-blueprint/ui/src /home/drew/code/ai-trading-blueprints/arena/src
| ID | Name | Mode | Description |
|---|---|---|---|
| 0 | SANDBOX_CREATE |
Cloud | Create a new sandbox container |
| 1 | SANDBOX_DELETE |
Cloud | Delete a sandbox and clean up |
| 2 | WORKFLOW_CREATE |
Cloud + Instance | Register a workflow template |
| 3 | WORKFLOW_TRIGGER |
Cloud + Instance | Trigger a registered workflow |
| 4 | WORKFLOW_CANCEL |
Cloud + Instance | Cancel an active workflow |
Internal: JOB_WORKFLOW_TICK (255) — cron-driven workflow scheduler, never on-chain.
Sandbox creation supports backend selection via metadata_json.runtime_backend:
docker(default)firecracker(microVM path; requires operator runtime support)tee(forces TEE provisioning path)
UI behavior:
- "Runtime Backend" selector writes to
metadata_json.runtime_backend. - Selecting
teeforcestee_required=true. - Selecting
firecrackerforcestee_required=false(current release does not support Firecracker+TEE composition). - Selecting
firecrackerdisablesmetadata_json.portsinput (current Firecracker runtime does not support explicit port mappings).
- Canonical path is operator-signed direct reporting:
reportProvisioned(serviceId, sandboxId, sidecarUrl, sshPort, teeAttestationJson)reportDeprovisioned(serviceId)
- Authentication is
msg.sender+ Tangle membership (isServiceOperator(serviceId, msg.sender)). onServiceInitializedstores desired state (owner/config) but does not claim runtime readiness.- Runtime startup auto-provisions locally, then reports provision directly to manager.
- State machine remains strict:
- report provision when already provisioned => revert
AlreadyProvisioned - report deprovision when not provisioned => revert
NotProvisioned
- report provision when already provisioned => revert
All data endpoints require PASETO v4 session auth (EIP-191 challenge-response).
POST /api/auth/challenge— Get a nonce to signPOST /api/auth/session— Exchange signed challenge for PASETO tokenDELETE /api/auth/session— Revoke current session
GET /api/sandboxes— List caller's sandboxesGET /api/sandboxes/{id}/ports— List exposed container portsPOST /api/sandboxes/{id}/exec— Execute a commandPOST /api/sandboxes/{id}/prompt— Run an AI promptPOST /api/sandboxes/{id}/task— Run an AI taskPOST /api/sandboxes/{id}/stop— Stop a sandboxPOST /api/sandboxes/{id}/resume— Resume a stopped sandboxPOST /api/sandboxes/{id}/snapshot— Upload a snapshotPOST /api/sandboxes/{id}/ssh— Provision SSH keyDELETE /api/sandboxes/{id}/ssh— Revoke SSH keyPOST /api/sandboxes/{id}/secrets— Inject secretsDELETE /api/sandboxes/{id}/secrets— Wipe secretsANY /api/sandboxes/{id}/port/{port}— Proxy to container port
GET /api/sandbox/ports— List singleton sandbox portsPOST /api/sandbox/exec— Execute a commandPOST /api/sandbox/prompt— Run an AI promptPOST /api/sandbox/task— Run an AI taskPOST /api/sandbox/stop— Stop the singleton sandboxPOST /api/sandbox/resume— Resume the singleton sandboxPOST /api/sandbox/snapshot— Upload a snapshotPOST /api/sandbox/ssh— Provision SSH keyDELETE /api/sandbox/ssh— Revoke SSH keyANY /api/sandbox/port/{port}— Proxy to singleton container port
Note: /api/sandbox/secrets is not currently exposed; secret provisioning is currently sandbox-scoped (/api/sandboxes/{id}/secrets).
GET /health— Runtime backend + store health check (503 when degraded)GET /readyz— Strict readiness probe (503 unless all subsystems healthy)GET /metrics— Prometheus metricsGET /api/provisions— List provision status
GET /health response contract:
status:"ok"or"degraded"checks.runtime.status: runtime probe status ("ok"or"error")checks.store.status: local state-store status ("ok"or"error")runtime_backend: active runtime backend label (docker/firecracker/tee/invalid)runtime_error: nullable backend error string when runtime probe fails
GET /readyz response contract:
200:{ "status": "ready" }503: includesruntime_backend,runtime(boolean),store(boolean), andruntime_error
- Auth: EIP-191 challenge-response → PASETO v4.local tokens (1h TTL)
- Encryption: ChaCha20-Poly1305 at-rest encryption for tokens/env in stored records
- Container hardening:
cap_drop ALL,SYS_PTRACEonly,no-new-privileges,readonly_rootfs, PID limit 512, ports bound to127.0.0.1 - Rate limiting: 3-tier (auth 10/min, write 30/min, read 120/min) with XFF spoofing prevention
- Circuit breaker: Per-sandbox health tracking with 30s cooldown
- Session caps: 10K challenges, 50K sessions max with background GC
- SSRF protection: Snapshot destinations validated (HTTPS/S3 only, no private IPs)
- Rust 1.88+
- Docker
- Foundry (for contracts)
- Node.js 22+ / pnpm (for UI)
SIDECAR_IMAGE— Docker image for sidecar containersSESSION_AUTH_SECRET— Symmetric key for PASETO tokens and at-rest encryption
| Variable | Default | Description |
|---|---|---|
SIDECAR_PUBLIC_HOST |
127.0.0.1 |
Public hostname for sidecar access |
SIDECAR_HTTP_PORT |
8080 |
Container HTTP port |
SIDECAR_SSH_PORT |
22 |
Container SSH port |
SIDECAR_PULL_IMAGE |
true |
Pull image on first create |
REQUEST_TIMEOUT_SECS |
30 |
HTTP client timeout |
DOCKER_OPERATION_TIMEOUT_SECS |
60 |
Docker API call timeout |
OPERATOR_API_PORT |
9090 |
Operator API listen port |
SANDBOX_DEFAULT_IDLE_TIMEOUT |
1800 |
Idle timeout (seconds) |
SANDBOX_DEFAULT_MAX_LIFETIME |
86400 |
Max lifetime (seconds) |
SANDBOX_REAPER_INTERVAL |
30 |
Reaper check interval |
SANDBOX_GC_INTERVAL |
3600 |
GC interval |
SANDBOX_RUNTIME_BACKEND |
docker |
Default runtime backend (docker, firecracker, tee) |
FIRECRACKER_HOST_AGENT_URL |
— | Base URL for Firecracker host-agent API (required for runtime_backend=firecracker) |
FIRECRACKER_HOST_AGENT_API_KEY |
— | Optional API key header (x-api-key) for host-agent |
FIRECRACKER_HOST_AGENT_NETWORK |
bridge |
Network value sent in host-agent create payload |
FIRECRACKER_HOST_AGENT_PIDS_LIMIT |
512 |
PIDs limit sent in host-agent create payload |
FIRECRACKER_SIDECAR_AUTH_DISABLED |
false |
Explicitly disable sidecar auth for Firecracker (true only when sidecar auth is intentionally off) |
FIRECRACKER_SIDECAR_AUTH_TOKEN |
— | Static sidecar auth token for Firecracker records when auth is enabled |
WORKFLOW_CRON_SCHEDULE |
0 * * * * * |
Cron schedule for workflow ticks |
CORS_ALLOWED_ORIGINS |
localhost only |
Comma-separated CORS origins |
BSM_ADDRESS |
— | BSM contract address (instance mode) |
HTTP_RPC_ENDPOINT / RPC_URL |
— | Chain RPC endpoint |
Firecracker auth mode is explicit and mutually exclusive:
- set
FIRECRACKER_SIDECAR_AUTH_DISABLED=trueand leaveFIRECRACKER_SIDECAR_AUTH_TOKENunset, or - set
FIRECRACKER_SIDECAR_AUTH_DISABLED=falsewithFIRECRACKER_SIDECAR_AUTH_TOKENset.
# Build
cargo build --workspace
# Test
cargo test --workspace
# Format (must use nightly)
cargo +nightly fmt
# Lint
cargo clippy --workspace --tests --examples -- -D warnings
# Solidity
forge soldeer update -d && forge build && forge test -vvv
# UI
cd ui && pnpm install && pnpm test && pnpm dev
# Local dev (skip BPM bridge)
cargo run -p ai-agent-sandbox-blueprint-bin -- run --test-mode
# Real Firecracker job-path E2E (requires reachable host-agent + KVM host)
FIRECRACKER_E2E=1 FIRECRACKER_REAL_E2E=1 \
FIRECRACKER_HOST_AGENT_URL=http://127.0.0.1:3101 \
FIRECRACKER_HOST_AGENT_API_KEY=fc-test-key \
FIRECRACKER_SIDECAR_AUTH_DISABLED=true \
FIRECRACKER_TEST_IMAGE=/var/lib/firecracker/rootfs/sidecar.ext4 \
cargo test -p ai-agent-sandbox-blueprint-lib --test anvil runs_firecracker_jobs_end_to_end -- --nocapture --test-threads=1- Blueprint: A specification for a verifiable, decentralized service on Tangle Network. Blueprints define jobs, handle results, and manage the operator lifecycle.
- Operator: A node runner who registers to provide services defined by a Blueprint. Operators stake assets and earn rewards for honest execution.
- TEE (Trusted Execution Environment): Hardware-isolated execution environments (such as AWS Nitro Enclaves or Intel SGX) that provide confidentiality and attestation for sensitive computations.
- Sealed Secrets: Encrypted data that can only be decrypted inside a TEE. Secrets are sealed using ChaCha20-Poly1305 encryption and bound to a specific enclave identity.
- Attestation: Cryptographic proof that code is running inside a genuine TEE. Attestation reports are verified on-chain to establish trust.
- BlueprintRunner: The runtime that manages the lifecycle of a Blueprint operator, including job polling, execution, and result submission.
A Blueprint is a specification for an Actively Validated Service (AVS) on the Tangle Network. It defines the jobs an operator can perform, how results are verified, and what on-chain contracts govern the service lifecycle.
The sandbox supports AWS Nitro Enclaves, Azure Confidential Computing, GCP Confidential VMs, and Phala Network as TEE backends. Each backend provides hardware-level isolation and remote attestation.
Sandbox mode runs a multi-tenant fleet of Docker containers managed by the operator, suitable for shared workloads. Instance mode runs a single dedicated sandbox per service, providing stronger isolation. TEE Instance mode adds hardware attestation and sealed secrets on top of instance mode.
Secrets are encrypted using ChaCha20-Poly1305 and stored as sealed data. Only attested TEE enclaves with the correct identity can decrypt them. The operator API provides endpoints for secret provisioning and retrieval within authenticated sessions.
Install Rust 1.88+, Docker, and Foundry. Build with cargo build, deploy the Solidity contracts, and register as an operator using the cargo-tangle CLI. See the deployment section above for detailed steps.
MIT OR Apache-2.0
