A user reports the agent did something wrong yesterday. You have logs, but they're scattered, not signed, and you can't prove they weren't modified. Compliance asks for a tamper-evident trail and you don't have one.
- Customer disputes about what the agent did or said
- Security or compliance asks for an immutable audit trail
- You need to replay an exact session for debugging
Anything touching money, regulated data, customer contracts, or production infra. Internal tools where 'who did what' matters.
Throwaway prototypes. Audit overhead is real and the storage adds up.
The YAML
Drop this into an app.yaml. Adjust the credential refs and module names to fit your existing setup.
1execution:2 hooks:3 - id: audit_tool_calls4 "on": tool_end5 condition: { type: always }6 action:7 type: log8 target: audit9 fields:10 session_id: "{{session.id}}"11 user_id: "{{session.user_id}}"12 tool: "{{tool.name}}"13 params: "{{tool.params}}"14 status: "{{tool.status}}"15 duration_ms: "{{tool.duration_ms}}"16 tokens: "{{tool.tokens}}"17 chain: hash # SHA-256 chained, tamper-evident1819 - id: audit_credential_reads20 "on": tool_start21 condition: { type: tool_name, match: "credential" }22 action:23 type: log24 target: audit25 fields:26 credential_ref: "{{tool.params.credential.ref}}"27 scope: "{{tool.params.credential.scope}}"28 accessed_by: "{{session.user_id}}"2930agents:31 - id: ops32 modules: [{http: [post]}, {filesystem: [read, write]}]33 brain: { model: claude-sonnet-4-6, credential: anthropic_main }How it works
Walking through the YAML one block at a time so the design is clear, not memorised.
Universal capture on tool_end
One hook with condition: always covers every tool call. No per-tool wiring, no risk of missing the one that mattered.
Hash chain for tamper evidence
Each audit row carries the SHA-256 of the previous row. Modify a row and the chain breaks visibly. POST /api/admin/credentials/audit/verify confirms the chain on demand.
Credential reads are logged separately
Knowing the agent read credential X at time T is a compliance requirement in many jurisdictions. The second hook makes it explicit.
Replay-ready data
Session id, params, status, and timestamps are enough to reconstruct any session. Combined with conversation history, you can answer 'what did the agent do at 14:32?' definitively.
Other ways to solve it
The pattern above is not the only answer. Here is when something else is the right call.
Application-level logging
Sprinkle log statements in the modules you write. Easier, scattered, no signing, no chain.
External SIEM forwarding
Ship every event to Splunk, Datadog, or a log lake. Strong analytics, depends on the network, doesn't give you per-row signing by default.
How credentials work on Digitorn: an encrypted vault driven from YAML
Get the next post in your inbox.
Engineering notes from the Digitorn team. No marketing, no launch announcements, no "10 prompts that will change your life". Just the things we write that we'd want to read.