Terrarium

A self-hosted, single-tenant runtime for autonomous Claude Code agents.

Each session runs the real Claude Code engine (driven by the Claude Agent SDK) inside a hardened, ephemeral sandbox behind a per-session egress firewall — and the credential is injected at the network boundary, so it never enters the sandbox.

Get started View on GitHub


What it gives you

The Claude Code agent loop as a managed service: launch agents from reusable configs, drive them from a web console or an SDK, and keep every session isolated — non-root, capability-less, seccomp-filtered, with kernel-enforced egress default-drop and a Rust MITM mediator (Warden) that injects credentials, allow-lists destinations, and signs an audit receipt for every connection.

Capability What it means
Hardened sandbox Non-root, CapEff=0, seccomp (RuntimeDefault), no service-account token, kernel egress default-drop, DNS cut.
Credential never in the sandbox Warden injects the real token at egress. The agent sees only a realistic decoy behind a generic “corporate proxy” CA.
Console-managed egress Allow, deny, inspect and kill — edited live in the UI and propagated to running sessions.
Durable sessions Survive orchestrator restarts by reattaching to live sandboxes.
Rewind and edit Restore the workspace or the conversation to a past turn, Claude Code style.
Concurrent runs per agent An agent is just configuration; parallel sessions auto-isolate their memory.
Unified logs view Session activity and egress decisions, filterable by agent, session, type or host.

Where to go next

  • Quickstart — run it locally with Docker in five commands.
  • Architecture — the control plane, the sandbox, and how a session actually flows.
  • Security model — the layers, what an agent cannot do, and an honest account of what the DLP scan is and isn’t.
  • Configuration — every environment variable that matters.
  • SDK — drive sessions from Python.
  • Deployment — Docker, Kubernetes, or a single VPS with shunt; a ready shunt.toml ships in the repo.

Status

Terrarium is at 0.1.0 — the first public release. It has been running a single-operator deployment for some time, but the API surface is not yet frozen and the Kubernetes path ships no reference manifests (see Deployment). Expect breaking changes before 1.0; they will be flagged in the changelog.