Constle Architecture

Four layers. None inside the agent.

Every layer runs in the host constle process. The agent gets a sandbox and a proxy. Nothing it can reach can switch a rule off.

01Layers

Three ship. The fourth doesn't exist yet.

4

Commerce Planned

Agents discovering and paying each other for work. Once identity and spending enforcement are solid. A direction, not a scheduled milestone.

ROADMAP.md

3

Communication Shipped

A2A: Ed25519-signed envelopes, host-side sign and verify, declared peers only. The sandbox does no cryptography and never sees a peer's real endpoint. There is no discovery mechanism, by design.

internal/a2a/

2

Identity & governance Shipped

did:key identity, the signed and hash-chained audit log, human gates at the MCP gate proxy, and the per-run / per-day USD ledger.

internal/identity · internal/audit · internal/mcpgate · internal/spending

1

Runtime & sandbox Shipped

A Firecracker microVM or a two-network Docker sandbox, no default route, and a Squid egress allowlist. The supervisor enforces duration and memory.

internal/sandbox/

02Chokepoints

Enforcement sits where traffic must pass.

Constle assumes nothing inside the sandbox is trustworthy. A control that relied on the agent reporting its own behaviour would only work when it wasn't needed.

ChokepointWhenEnforces
Sandbox environment constructionbefore the agent existscredentials
Squid egress proxyper runsandbox.network.allowed_hosts
MCP gate proxyper runmcp.servers[].tools, human_gates.*, spending.* metering
A2A gate + host listenerper runa2a.peers authorization, envelope signing and verification
Supervisor processper runlimits.max_duration_seconds, sandbox.memory_mb

The first row acts before the agent starts: the environment is composed, the sandbox is started with it, and there's no later moment to ask for more.

03Isolation

Capabilities set the floor.

Each declared capability needs a minimum isolation level. A declared level may only strengthen that floor, never weaken it. Try it.

capabilities

      
!What capabilities is not

It is not a sandbox permission system. Declaring read_file grants nothing and omitting it removes nothing; the image and mounts decide file access. Capabilities are self-asserted: an agent that omits external_transfer and declares isolation: none still runs at none. Capabilities naming irreversible actions are reported by validate as needing approval. That is advice; only human_gates.require_approval_for gates anything.

04Backends

Two backends, one ruleset.

Both render their proxy policy from the same function, so Docker and Firecracker enforce the same allowlist.

DockerFirecracker
BoundaryTwo-network container sandboxmicroVM (hardware isolation)
Route outNetwork created --internal; one on-link route, no default routeNo ::/0 or global route; per-run nftables table drops the tap
IPv6Off, via explicit --ipv6=falseKernel link-local fe80:: only
Selected whenAuto-detected, or --backend=dockerAuto-detected, --backend=firecracker, or required by isolation: kernel

The generated Squid config is parsed by a real Squid in the test suite, and any complaint fails the build. Want another backend? gVisor is on the contributing wish list.

05Tool calls

Life of an MCP tool call.

  1. 1

    The agent calls a name

    It only knows CONSTLE_MCP_<ID>_URL, which points to the gate. The real server URL stays on the host.

  2. 2

    The gate reads the call

    Only POST, GET, DELETE. A body with duplicate or case-colliding keys is refused. Ambiguous paths and protocol upgrades are refused.

  3. 3

    Tool allowlist

    A tool not in mcp.servers[].tools is blocked at the gate.

  4. 4

    Human gate

    If the tool name is in require_approval_for, the call waits for the terminal or a signed webhook decision.

  5. 5

    Forward and meter

    Forwarded to the declared endpoint only. The response is metered against pricing; over the cap, the run is killed.

  6. 6

    Record

    Each step lands in the signed, hash-chained audit log.

06Host-only

What never enters the sandbox.

  • ~/.constle/identities/<name>/The agent's private key, mode 0600.
  • mcp.servers[].urlReal MCP endpoints. The agent sees only the gate.
  • a2a.peers[].endpointReal peer endpoints. The agent can only name a peer.
  • credentialsOnly the variables the Agentfile names, and nothing else from your shell.
  • url_secret_refThe webhook URL lives in a host env var, not the Agentfile.
  • ~/.constle/webhook-keys/The approver's signing key from constle webhook-keygen. It goes to whoever runs the decision endpoint, never to the agent.

Threat model and known limitations