Constle Quickstart
Sixty seconds to a sandboxed agent.
Verified end to end on Linux + Docker against constle v0.5.0. Copy and paste as-is.
-
1
Install the CLI
curl -fsSL https://constle.dev/install | shiwr -useb https://constle.dev/install.ps1 | iexgit clone https://github.com/constle/constlecd constlego build -o constle ./cmd/constleNeeds Go 1.26+.
The installer refuses an archive whose SHA-256 doesn't match the release's
checksums.txt, and checks cosign's signature when cosign is on your PATH. Verifying a release -
2
Check the example Agentfile
Nothing runs yet.
./constle validate examples/basic-agent/agent.yaml✓ examples/basic-agent/agent.yaml is valid name: basic-agent version: 0.1.0 isolation: network (inferred from capabilities) image: basic-agent:latest memory: 512MB allowed: api.groq.com credentials: GROQ_API_KEY, AGENT_TASK ⚠️ warning: spending limits are declared but NOT enforced: no mcp.servers entry declares a pricing block, so there is nothing to meter.That warning is the design working. A declared cap with nothing metering it is called out loudly instead of quietly looking real.
-
3
Build the image and run it
docker build -t basic-agent:latest examples/basic-agentexport GROQ_API_KEY=gsk_...export AGENT_TASK="What is 2+2?"./constle run examples/basic-agent/agent.yamlconstle v0.5.0 → parsing examples/basic-agent/agent.yaml ✓ Agentfile valid agent: basic-agent v0.1.0 isolation: network memory: 512MB network: restricted → api.groq.com credentials: GROQ_API_KEY, AGENT_TASK spending: run≤$0.10 (NOT ENFORCED — no priced MCP servers) → detecting backend ✓ backend: docker → starting sandbox... ✓ sandbox started (run_id: 76935e132f9be8e9) ┌─ agent output ────────────────────────── │ 2 + 2 = 4 └───────────────────────────────────────── ✓ run finished exit=0 duration=2.7s audit log: ~/.constle/logs/basic-agent-2026-08-08.jsonl?Where's
--env?There isn't one. An agent receives exactly the host variables its
credentials:names, and nothing else from your environment. Only the variable name goes in the manifest; the value stays in your shell and is never written to the image, the manifest or the audit log. The free Groq key comes from console.groq.com. -
4
Sign the audit trail
Optional, about 20 seconds more.
./constle identity create my-agent [email protected]Paste the printed
did:key:…into the manifest underidentity.did, run again, then:./constle audit verify ~/.constle/logs/my-agent-$(date -u +%F).jsonl✓ audit log verified: ~/.constle/logs/my-agent-2026-08-08.jsonl entries: 2 (all signatures valid, hash chain intact) signed by: did:key:z6MkgroKowQYDZjDmqbn82mJv4YFPKowS2xDhxGYrp4u3P1o
Edit a single byte of that file and run it again:
error: TAMPERING DETECTED in ~/.constle/logs/my-agent-2026-08-08.jsonl line 1: invalid_signature — signature does not verify against did:key:z6Mkg… — the entry was edited after signingWith
identity.didset,constle runalso fails closed: no matching private key on this machine, no run. -
5
Gate a tool call
Pause a named MCP tool until a human decides.
./constle webhook-keygen approver✓ webhook signing key created: "approver" did: did:key:z6Mk… key file: ~/.constle/webhook-keys/approver (mode 0600 — never leaves this machine) this key is NOT an agent identity — it authenticates the human approving gated calls, not the agent making them.
human_gates: enabled: true require_approval_for: - pay_invoice # exact MCP tool name approver_pubkey: did:key:z6Mk… # required when gating notify: - channel: webhook url_secret_ref: HUMAN_GATE_WEBHOOK_URL on_timeout: abort # default; stop, never proceedAt run time the call waits for whichever answers first: the terminal prompt or a signed decision from your endpoint. How decisions are verified
06Reference
Every constle command.
| Command | What it does |
|---|---|
constle [--no-animation] | Startup screen and command overview |
constle init | Scaffold a starter Agentfile (agent.yaml) in the current directory |
constle run [--backend=docker|firecracker] [--accept-isolation=<level>] <agentfile> | Run an agent in an isolated sandbox. --accept-isolation (none, process, network) knowingly runs below the declared level, and is recorded. |
constle validate <agentfile> | Validate without running; prints resolved isolation and every unenforced declaration |
constle ps | List running and recent Constle-managed agents |
constle stop <run-id> | Stop a running agent by run ID |
constle identity create <name> [--owner=<email>] | Generate an agent DID (Ed25519 keypair) |
constle identity show <name> | Show an agent's DID and key location |
constle webhook-keygen <name> | Generate a human-gates approver keypair (did:key) for approver_pubkey |
constle audit verify [--agentfile=<path>] [--did=…] [--approver-pubkey=…] <logfile> | Verify signatures and the hash chain, and re-verify recorded gate decisions. --agentfile takes both pins from the Agentfile. |
constle version | Print the version |
CONSTLE_ANIMATION | auto (default), never, always. The intro is always skipped for non-interactive output, NO_COLOR, TERM=dumb or terminals under 80×24. |
|---|---|
CONSTLE_REQUIRE_SIGNATURE | 1 makes the installer refuse any release without a verified cosign signature. |
url_secret_ref target | The host variable you name (for example HUMAN_GATE_WEBHOOK_URL) holds the webhook URL, so it never sits in the Agentfile. |
Next: your own Agentfile
constle initStart from the scaffold, not a copy of the example.
Field referenceHack on Constle
go build ./... && go test ./...Open an issue before anything beyond a small fix. New behaviour needs a test.
CONTRIBUTING.md