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.

A terminal installing Constle, validating the example Agentfile and running it: the agent prints 2 + 2 = 4 and the run finishes in 2.7 seconds.
  1. 1

    Install the CLI

    curl -fsSL https://constle.dev/install | sh

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

    Build the image and run it

    docker build -t basic-agent:latest examples/basic-agent
    export GROQ_API_KEY=gsk_...
    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
    ?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. 4

    Sign the audit trail

    Optional, about 20 seconds more.

    ./constle identity create my-agent --owner=you@example.com

    Paste the printed did:key:… into the manifest under identity.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 signing

    With identity.did set, constle run also fails closed: no matching private key on this machine, no run.

  5. 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 proceed

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

CommandWhat it does
constle [--no-animation]Startup screen and command overview
constle initScaffold 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 psList 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 versionPrint the version
Environment
CONSTLE_ANIMATIONauto (default), never, always. The intro is always skipped for non-interactive output, NO_COLOR, TERM=dumb or terminals under 80×24.
CONSTLE_REQUIRE_SIGNATURE1 makes the installer refuse any release without a verified cosign signature.
url_secret_ref targetThe 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 init

Start from the scaffold, not a copy of the example.

Field reference

Hack on Constle

go build ./... && go test ./...

Open an issue before anything beyond a small fix. New behaviour needs a test.

CONTRIBUTING.md

Read the limits first

Five known gaps, all deliberate and stated in the code.

Known limitations