Getting started Quickstart

Docs Getting started

Quickstart

Verified end to end on Linux + Docker against constle v0.5.0. Copy and paste as-is.

On this page

You will need

Go 1.26+ to build the CLI (or the one-line installer), Docker for the sandbox backend, and a free Groq API key for the example agent. Firecracker is optional: the CLI auto-detects a backend.

Explainer · 0:53 · Quickstart · English captions
Transcript

0:00 From zero to a sandboxed agent — verified end to end on Linux with Docker. Clone the repo and build the CLI with Go — or use the one-line installer, which checks the release checksum. Validate the example Agentfile. Nothing runs yet — and notice the warning: that spending cap has nothing to meter. Build the example image, export the two credentials it declares, and run it. Nothing else from your environment crosses into the sandbox. Create an identity, paste its DID into the Agentfile, run again — and verify the signed audit log. Edit one byte, and verify catches it — at the exact line.

0:44 Constle is open source and pre-1.0. The docs are at docs.constle.dev.

1. Install the CLILink to this section

Build it from source (Go 1.26+):

git clone https://github.com/constle/constle
cd constle
go build -o constle ./cmd/constle

Or install a pre-built binary for Linux, macOS or Windows:

curl -fsSL https://constle.dev/install | sh        # Linux, macOS
iwr -useb https://constle.dev/install.ps1 | iex    # Windows PowerShell

The installer fetches checksums.txt for the release it is installing and refuses to unpack an archive whose SHA-256 does not match. When cosign is on your PATH it checks the release workflow's signature over checksums.txt first, pinned to the identity in Verifying a release, and aborts if that fails; without cosign it says so on the terminal and enforces the checksum alone. Downloading an archive by hand from the releases page skips all of this.

2. Check the example manifestLink to this section

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 gets called out loudly instead of quietly looking real. See Spend caps and metering and Known limitations.

3. Build the example image and run itLink to this section

docker build -t basic-agent:latest examples/basic-agent
export GROQ_API_KEY=gsk_...            # free key: https://console.groq.com
export AGENT_TASK="What is 2+2?"
./constle run examples/basic-agent/agent.yaml
constle 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

There is no

--env flag An agent receives exactly the host variables its manifest declares under credentials: (the example declares GROQ_API_KEY and AGENT_TASK) and nothing else from your environment crosses into the sandbox. Only the variable name goes in the manifest; the value stays in your shell and is never written into the image, the manifest or the audit log. Declare nothing and the agent gets nothing.

4. Sign the audit trailLink to this section

Optional, about 20 seconds more. Create an identity for the agent:

./constle identity create my-agent [email protected]

Paste the printed did:key:... into the manifest under identity.did, run again, then verify the log:

./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 signing

With identity.did set, constle run also fails closed: if the manifest names a DID with no matching private key on this machine, the run refuses to start rather than proceeding under an identity it cannot prove. More in Audit log and verification.

5. Gate a tool callLink to this section

Pause a named MCP tool call until a human decides. First create an approver key. It is not an agent identity: it authenticates the human approving, not the agent making the call.

./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.

  give the private key file to whoever operates the decision
  endpoint, and paste the DID into your Agentfile:

    human_gates:
      approver_pubkey: did:key:z6Mk…

Then declare the gate in the Agentfile:

human_gates:
  enabled: true
  require_approval_for:
    - pay_invoice                 # the exact MCP tool name
  approver_pubkey: did:key:z6Mk…  # required when require_approval_for is set
  notify:
    - channel: webhook
      url_secret_ref: HUMAN_GATE_WEBHOOK_URL
  on_timeout: abort               # the default: refuse the call, stop the run

At run time the call waits for whichever answers first: the terminal prompt, or a signed decision from your endpoint. Human gates covers the prompt, the webhook protocol and how decisions are verified.

Where to go nextLink to this section

  • The Agentfile: every field the runtime consumes, and what enforces each one.
  • Architecture: what the sandbox, the proxy and the gates each do during that run.
  • Known limitations: why the run above printed NOT ENFORCED, and four other gaps like it.
  • CLI reference: every constle command.

Something wrong or unclear? Open an issue. The specifications on these pages are copies of spec/ in constle/constle.