Constle documentation
Constle is a runtime that enforces what an AI agent is allowed to do (network, spend, approvals, identity) from outside the agent, so a compromised agent cannot turn the rules off.
Early and pre-1.0
Constle is early and solo-maintained, and its interfaces may change between releases. Read Known limitations before you rely on any of this.
Source release coming soon
The documentation is published first. The source, the installers and signed releases are not public yet, so these pages give no install commands or repository links. Every command and output here is Constle as it behaves today. More in Project status.
You declare the policy in one YAML file, the Agentfile. Constle runs the agent inside a sandbox with no default route, routes every connection through an allowlisting proxy, meters cost at the tool-call boundary, pauses sensitive calls for a human, and writes a signed, hash-chained audit log. None of that lives in the agent's process, so there is nothing in it for a prompt injection to disable.
Text description
The agent process runs in the sandbox. Its requests leave by one of two chokepoints, both outside the agent.
Network calls go to the Squid proxy, which checks network.allowed_hosts and marks each one ALLOWED or BLOCKED.
Tool calls go to the MCP gate proxy, which checks human_gates.require_approval_for and hands a matching call to a human at the terminal or through a signed webhook. APPROVED calls are forwarded. DENIED calls are refused, and a gate with no decision by its deadline is resolved by on_timeout: under the default abort the call is refused and the run stops (under proceed it would be forwarded without approval).
Every outcome (allow, block and gate decision alike) is written by internal/audit/ to the signed, hash-chained audit log under ~/.constle/logs/. Both outcomes are logged the same way: the block is how you find out it happened.
Constle has three layers, all in the host constle process. The quickstart walks through validating, running and verifying a real agent under enforcement, with the real output.
Enforcement, demonstratedLink to this section
An agent whose manifest declares allowed_hosts: [api.groq.com], reaching for one declared host and one undeclared one:
┌─ agent output ──────────────────────────
│ https://api.groq.com/ CONNECT allowed TLS tunnel opened, server replied
│ https://evil.example.com/ CONNECT refused Tunnel connection failed: 403 Forbidden
└─────────────────────────────────────────
$ grep network ~/.constle/logs/egress-probe-2026-08-08.jsonl
{"event":"network_allowed","details":{"bytes":5314,"host":"api.groq.com","http_status":200,"method":"CONNECT"}}
{"event":"network_blocked","details":{"bytes":3404,"host":"evil.example.com","http_status":403,"method":"CONNECT"}}The second request never left the sandbox: the proxy declined to open the tunnel. Both attempts land in the audit log either way; the blocked one is how you find out it happened. Raw-IP bypass attempts, IPv6 and the DNS trust boundary are covered in Network isolation.
What Constle enforcesLink to this section
Eight capabilities.
Text description
Sandboxed execution (shipped): Firecracker microVM or two-network Docker sandbox, no default gateway. Fails closed rather than silently running on a weaker boundary.
Network egress (shipped): Squid proxy allowlist, name-based matching. Raw-IP bypass is blocked too. Every allow and block is audited.
Max duration (shipped): Agent is killed when max_duration_seconds elapses; recorded as terminated_by_limit.
Audit log (shipped): Signed, hash-chained JSONL per agent per day. constle audit verify catches tampering.
Spending limits (shipped): Per-run / per-day USD caps, metered at the MCP gate. Counted after each call; daily ledger durable across runs.
Human gates (shipped): Protocol-aware gate proxy pauses named tool calls for approval; with no decision, on_timeout decides (default abort).
Cryptographic identity (shipped): W3C did:key (Ed25519). Private key never enters the sandbox; fails closed if missing. Not on Windows.
Agent-to-agent messaging (shipped): Signed envelopes to declared peers only. No discovery mechanism, by design.
The same, in full: every mechanism in detail
| Capability | Mechanism | Status |
|---|---|---|
| Sandboxed execution | Firecracker microVM (hardware isolation) or a two-network Docker sandbox with no default gateway. Auto-detected, or forced with --backend=docker|firecracker. A declared isolation: level is a minimum: it may be stronger than the declared capabilities require but never weaker, or the Agentfile is rejected at validate time. isolation: kernel selects Firecracker and the run fails closed if Firecracker is unavailable, unless an operator explicitly accepts a weaker boundary with --accept-isolation=<level>, which is named and recorded. |
Shipped |
| Network egress | All egress traverses a Squid proxy allowlisting network.allowed_hosts. Matching is name-based (dstdomain) with reverse lookups off, so a raw IP is denied, including the real IP of an allowed host and an address whose PTR record names one. Destinations in loopback, link-local, metadata and private ranges are refused on the resolved address, and CONNECT is confined to 443. Every allow and every block is an audit event. On the Docker backend, the agent's network is created with the isolated-gateway option, and a Docker Engine that cannot provide it is refused. |
Shipped |
| Max duration | The agent is killed when limits.max_duration_seconds elapses; the kill is recorded as terminated_by_limit. |
Shipped |
| Audit log | JSONL per agent per UTC day. With identity.did set, every entry is Ed25519-signed and hash-chained; constle audit verify checks every entry's signature and its link to the entry before it, and reports the line that fails. A gate decided over the signed webhook also records the approver's signed decision, which constle audit verify --agentfile=… re-verifies. |
Shipped |
| Spending limits | max_per_run_usd and max_per_day_usd, metered at the MCP gate against each server's declared pricing. Costs are counted after each call, so spending can pass a cap before the run is stopped. The daily ledger is durable across runs, keyed by DID so a rename can't reset it. A priced server whose response omits a declared usage value kills the run. Scope caveats: limitations 2 and 3. |
Shipped |
| Human gates | Declared MCP servers are reachable only through a protocol-aware gate proxy. A matching tools/call pauses for approval at the terminal and, with approver_pubkey set and a notify webhook URL resolving, at a signed decision channel too; the first decision wins. A decision that arrives is verified and can only deny. With no decision by the deadline, on_timeout decides (default abort). Matching caveat: limitation 1. |
Shipped |
| Cryptographic identity | W3C did:key (Ed25519). The private key stays at ~/.constle/identities/<name>/ (mode 0600) and never enters the sandbox. constle run fails closed on a declared DID with no local key. Not on Windows: limitation 7. |
Shipped |
| Agent-to-agent messaging | Signed envelopes to explicitly declared peers only. The host signs and verifies; the sandbox does no cryptography and is never given a peer's real endpoint. No discovery mechanism exists, by design. Replay caveat: limitation 4. | Shipped |
Every layer runs in the host constle process: the agent's private key, the real MCP server URLs and the real A2A peer endpoints never enter the sandbox. API keys you declare under credentials do: they are passed in as environment variables. Constle is not a framework: it doesn't decide how an agent reasons or plans, and LangGraph, CrewAI or hand-rolled code run inside it unchanged. More in What Constle is not and Why Constle.
Find your way aroundLink to this section
The guides start from one job each: sandbox a coding agent, stop exfiltration, approve MCP tool calls, cap spend, verify a log.
Getting started
- QuickstartValidate an Agentfile, give the agent an identity, run it in a sandbox, verify its signed audit log and gate an MCP tool call, with the real output.
- Known limitationsSeven places where an Agentfile field looks stronger than the runtime is, each traced to the code, plus what Constle leaves out of scope by design.
- What Constle is notNot an agent framework, a cloud, a monitoring overlay, a TLS-inspecting proxy, a filesystem policy engine or a fleet platform. Where Constle stops.
- Why ConstleWhy the rules belong outside the agent, the four choices Constle makes beyond that, how it compares with other approaches, and what it deliberately does not do.
Guides
- All guidesTask-by-task guides: sandbox a coding agent, stop exfiltration, approve MCP tool calls, cap spend, contain prompt injection and verify audit logs.
- Agentfile in 5 minutesWrite a first Agentfile: scaffold it, set the network, credentials, isolation and limits, read what validate tells you, and avoid the fields that do nothing.
- Sandbox a coding agentRun a CLI coding agent headless in a sandbox with no default route, one allowed API host and only the variables you declare, then check what it tried to reach.
- Stop data exfiltrationGive an AI agent one way out to the internet, an allowlist it cannot step around, and see which exfiltration channels that closes and which it leaves open.
- MCP tool allowlistsPut every remote MCP server behind a gate the agent cannot skip: the real URL stays on the host, only listed tools pass, and ambiguous requests are refused.
- Approve MCP tool callsHold a named MCP tool call until a person approves it, at the terminal or with an Ed25519-signed decision, and refuse the call when nobody answers.
- Cap agent spendingSet per-run and per-day USD caps on an AI agent's priced tool calls, metered at the MCP gate, and see exactly which spending those caps do not cover.
- Contain prompt injectionAssume an injected instruction succeeds, then limit what the agent can reach, call, spend and receive, and how long it runs. One Agentfile, and the gaps it leaves.
- Agent identityCreate a did:key identity per agent, keep its private key off the sandbox, and use it to sign the audit log, key the daily spend ledger and sign A2A calls.
- Verify an agent's logSign every audit entry with the agent's key, read the events that matter, and check the log offline with constle audit verify, pinned to the identity you expect.
How it works
- ArchitectureConstle’s three layers and the chokepoints where each rule is enforced (egress proxy, MCP gate, A2A gate, supervisor), all outside the agent.
- Network isolationHow the sandbox's no-default-route topology and the Squid allowlist proxy combine into a network policy the agent cannot step around, and where that stops.
- Spend caps & meteringPer-run and per-day USD caps, metered at the MCP gate against each server's declared pricing, and exactly which traffic that does not cover.
- Human gatesPause named MCP tool calls until a human decides, at the terminal or through an Ed25519-signed webhook decision, and exactly what happens when nobody answers.
- Audit log & verificationThe signed, hash-chained JSONL audit log, how constle audit verify catches an edited, deleted or reordered line, and what an intact chain does and does not prove.
- IdentityEach agent's W3C did:key (Ed25519) identity, where its private key lives, how a run fails closed without it, and how it signs the audit log.
- Agent-to-agent (A2A)Signed agent-to-agent calls between explicitly declared peers, signed and verified by the host, delivered into the sandbox only after verification.
Reference
- The AgentfileOne YAML file declares what an AI agent may reach, call and spend. An annotated example, the four enforcement labels, and every section at a glance.
- Field referenceThe complete AgentManifest specification: every section, field, type, default, validation rule and enforcement label.
- CLI referenceEvery constle subcommand and flag, the environment variables it reads, and the startup screen.
- ReleasesNo release is published yet. What releases carry, and what the installers will check, once the source is published.
Project