EN · TR · Security · Verax body
An audit trail for AI agents, written before the tool runs.
When an AI agent calls a tool (reads a table, sends a message, asks to spend), most setups keep a log line written afterwards by the same process that did the work. Verax writes the record first.
Verax body is an open-source MCP server (Apache-2.0) that sits between the agent and its tools. Every tools/call passes a fail-closed policy, and the decision is signed and written to a ledger on your machine before anything runs.
What one call leaves behind
- A signed decision: allow, deny or defer. A call with no token is turned away and no line is written. A refusal of an authorized call is recorded the same way as an allow.
- A
policyHashnaming the rule set that decided, and aninputsHashover the inputs document the agent declares, when it declares one. - For a call that ran, an effect row bound to its decision by
effectHash, including a call that threw.
Calls a person has to approve
A call the policy holds becomes defer. The documented path on a released install is verax approve on that machine. The approver's operator id is bound into the record by hash, and a CLI approval stays unsigned. Since 0.4.2 an HTTP approval requires a passkey assertion when an operator is registered; verax verify checks each signed approval again against the operator's public key. The launcher that opens that panel, verax desktop, is not released. There is no auto-approve path and no remote approver.
A spend request is capped by payee, amount, currency and a daily limit, and always waits for an operator. Verax records the authorization. It does not move money.
Checking the trail without trusting us
verax verify <stateDir> reads a ledger directory with no body running and nothing on the network. It reports four things separately: how many signatures verify, whether the record chain is unbroken, whether each effect is bound to a decision, and which key answered.
Checking against the key carried in the records proves the files agree with each other, not that the key was ever yours. Pin a key you hold with --key.
What it does not do
- It does not filter prompt injection. The policy sees the tool name and the token's scopes, and reads arguments in two places: spend (currency, cap per call, payee list, daily limit) and the recipient host of message.send. Since 0.8.0 a policy can also name data classes and file types: a call's arguments are scanned when its classes include mask, local or block, and a tool's result when its result classes include mask or block. Without them the policy reads no other argument text and no tool result.
- It is not a third-party witness. The witness process runs on the same host under the same operator: a separate key, not a separate trust domain.
- It does not notice a ledger that was deleted rather than altered.
- None of this has run against a paying customer's production traffic yet. The pilot drills are tests, not a live deployment.
Try it
npx @verax-ai/body demo starts a local body with a temporary ledger and records an allow, a signed refusal and a held spend through the real /mcp path.
Code: github.com/verax-ai/verax · What is carried and what stays unproven: STATUS.md · Sample panel: verax-ai.com/panel/?demo=1 (sample data, no body behind it).