Get release news

Quickstart

A sandboxed agent, step by step.

What Constle does, step by step, with its output, abridged.

    each step’s output, one row of pixels per line, abridgeda warningtampering detected
    1. 01

      The CLI

      The current source and its signed releases aren’t public yet.

      The steps below show Constle’s commands with their output, abridged.

      By signing up you agree to get release news by email. Privacy

    2. 02

      Check the example Agentfile

      Nothing runs yet.

      constle validateoutput, abridged

      $ 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
        time limit:  none
        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.
         cost is measured only at the MCP gate proxy (constle does not TLS-intercept
         generic allowed_hosts traffic); declare pricing on the MCP servers that cost money.
      
      ⚠️  warning: some declared credentials are not available on this machine:
         GROQ_API_KEY (not set on the host), AGENT_TASK (not set on the host)
         `constle run` will refuse to start until each one resolves —
         export the variable, or point credentials[].secret_ref at the one that holds it

      The spending warning is the design working. A declared cap with nothing metering it is called out loudly instead of quietly looking real.

    3. 03

      Create the agent’s identity

      $ constle identity create basic-agent --owner=you@example.com

      Paste the printed did:key:… into the manifest under identity.did. Only the public DID goes there, while the private key stays in ~/.constle/identities/ and never enters the sandbox. With identity.did set, every audit entry is signed, and constle run fails closed, so without a matching private key on this machine the run refuses to start.

    4. 04

      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
      Where’s --env?

      There isn’t one. An agent receives exactly the host variables its manifest names under credentials: (the example names GROQ_API_KEY and AGENT_TASK), 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. Declare nothing, and no host variable crosses in.

    5. 05

      Verify the audit log

      $ constle audit verify ~/.constle/logs/basic-agent-$(date -u +%F).jsonl

      Unpinned, it reports that the signatures are valid under the log’s own key, which was not pinned. Edit a single byte of that file and run it again, and it names the line that was changed. Pin the key with --agentfile=examples/basic-agent/agent.yaml (or --did=) and a clean log reports ✓ audit log verified.

    6. 06

      Gate a tool call

      Name an MCP tool, and its calls that pass through the gate wait for a person’s yes. By default, no answer in five minutes means the call is refused and the run stops.

      $ constle webhook-keygen approver

      agent.yamlthe gate

      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.

    07Reference

    The constle commands.

    constle [--no-animation]Startup screen and command overview
    constle initWrite 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. It prints the resolved isolation, and warns when declared gates or spend caps won’t be enforced and when the declared identity or credentials aren’t available here, and names each field you wrote that it accepts but does not enforce, and each A2A peer reached over plain http
    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.
    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.
    credentials namesThe only host variables passed into the sandbox, by name.