constle docs constle docs pre-1.0

Verify what an AI agent did: signed audit logs

An audit trail is only evidence if a change to it would show. With an identity declared, Constle signs and chains every entry, and constle audit verify names the line where an edit, a deletion or a reordering breaks the chain.

On this page

Source release coming soon

The source and installers are not public yet, so there is nothing to install today. This guide documents Constle as it behaves now. More in Project status.

What you'll getLink to this section

  • A JSONL audit log per agent per UTC day, written by the host, with every allow, refusal, tool call, approval and limit in it.
  • Ed25519 signatures on every entry and a SHA-256 hash chain between entries, verifiable offline.
  • A verification that is pinned to the agent identity and approver key you expect, not just to whatever key the file carries.

Why sign and chainLink to this section

A log the agent could write to is not evidence about the agent, and a log anyone with file access could edit quietly is not much evidence either. Constle writes the log from the host process, outside the sandbox. With identity.did set, each entry is signed with the agent's key and carries the hash of the line before it, so the file is checked as a sequence: change one byte and that line's signature fails; remove a line and the next one points at a hash that no longer exists. Format details: Audit log and verification.

1. Declare an identityLink to this section

shell
constle identity create basic-agent [email protected]

Paste the printed DID under identity.did. Without it, the log is still written, but unsigned. With it, constle run refuses to start if the key is missing, so a run cannot silently fall back to an unsigned log. More in Give each AI agent a verifiable identity.

2. Run the agent and find the logLink to this section

shell
constle run agent.yaml
ls ~/.constle/logs/

The log is ~/.constle/logs/<identity.name>-<YYYY-MM-DD>.jsonl, one file per agent per UTC day. A new run appends to the day's file, and its first entry chains to the last line already there.

3. Read the events that matterLink to this section

Each line is one JSON object with timestamp, run_id, agent_name, event and details, plus did, prev_hash and sig when signed. A few questions and the lines that answer them:

shell
LOG=~/.constle/logs/basic-agent-$(date -u +%F).jsonl
grep network_blocked "$LOG"          # where did it try to go that it wasn't allowed?
grep -E 'tool_call_start|mcp_tool_blocked' "$LOG"   # which tools did it call, or try to?
grep -E 'gate_(triggered|approved|denied|timeout)' "$LOG"   # what waited for a person, and what was decided?
grep -E 'spending_limit_reached|terminated_by_limit' "$LOG"   # did a cap or the time limit stop it?
Event Means
run_started, run_finished a run began and ended; run_started records the requested and achieved isolation and the credential names granted
network_allowed, network_blocked the proxy allowed or refused a connection (written at the end of the run)
tool_call_start, tool_call_end an MCP tool call was forwarded; the server, the tool and the argument size, never the arguments
mcp_tool_blocked, mcp_request_blocked the MCP gate refused a call or a request
gate_triggered … gate_timeout a human gate opened and how it resolved
spending_limit_reached, terminated_by_limit a cap or the time limit acted

The full list: Audit log.

4. Verify, pinnedLink to this section

shell
constle audit verify --agentfile=agent.yaml ~/.constle/logs/basic-agent-2026-08-08.jsonl
Output
✓ audit log verified: /home/you/.constle/logs/basic-agent-2026-08-08.jsonl

  entries:   2 (all signatures valid, hash chain intact)
  signed by: did:key:z6MkgroKowQYDZjDmqbn82mJv4YFPKowS2xDhxGYrp4u3P1o
  pinned:    DID matches the expected identity
  pins from: agent.yaml (identity.did, human_gates.approver_pubkey)

--agentfile takes both trust anchors from the Agentfile: the agent's identity.did and the human_gates.approver_pubkey that recorded approvals must verify against. --did= and --approver-pubkey= pin them one at a time. The check needs no network: the key is recovered from the DID string itself.

5. See what tampering looks likeLink to this section

Edit one byte of the file and verify again:

Output
error: TAMPERING DETECTED in /home/you/.constle/logs/basic-agent-2026-08-08.jsonl
  line 1: invalid_signature — signature does not verify against did:key:z6MkgroKowQYDZjDmqbn82mJv4YFPKowS2xDhxGYrp4u3P1o — the entry was edited after signing
Change Reported as
A line edited invalid_signature, at that line
A line deleted, with another after it chain_break_missing_entry, at that position
Lines reordered chain_break_reordered, at that position
The whole log re-signed with another key did_mismatch, when the DID is pinned

6. Keep a copy somewhere elseLink to this section

The log alone cannot show that lines were cut from its end: a shorter chain is still an intact chain. If that matters to you, copy each day's log, or at least its last line, to storage the host cannot rewrite, and compare later. This is a practice, not a Constle feature.

What an intact chain proves, and what it doesn'tLink to this section

Proves Does not prove
The runtime's own account of the run is unaltered since it was signed That the account is true: the host wrote it, and the host is trusted
The lines present are signed and in order, with none missing between them That none were cut from the end
A recorded webhook approval was signed by the pinned approver key over that call's digest Which arguments a signed digest was for: the log omits the arguments

Unpinned, verification only shows the log agrees with its own key, and says so. On Windows an Agentfile that sets identity.did does not run, so there are no signed logs there (limitation 7).

FAQLink to this section

Can the agent edit or delete its own audit log?Link to this section

The log is written by the host constle process to the invoking user's home directory, outside the sandbox; nothing in the sandbox can reach it. Someone with access to the host can change the file; verification then reports the line where the chain breaks, except for lines cut from the end (step 6).

Does verification need a network connection?Link to this section

No. constle audit verify recovers each key from the DID string, with no registry, no resolution service and no network call.

Are tool arguments or secrets written to the log?Link to this section

No. Tool calls are recorded by server, tool name and argument size; credentials are recorded by name only, never by value. Gate decisions record the identifying fields of the request, not its arguments.

Is this enough for compliance logging requirements?Link to this section

It gives you an automatically written, signed and chained record of what the runtime allowed and refused, which you can verify yourself. Whether that meets a particular regulation depends on the regulation and your system; ask whoever is responsible for that assessment.