Digitorn
Digitorn
← All patterns
data pattern

Audit everything

Every tool call, every credential read, hash-chained for replay.

The problem

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.

Symptoms
  • 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
Use when

Anything touching money, regulated data, customer contracts, or production infra. Internal tools where 'who did what' matters.

Skip when

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.

app.yaml
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.

01

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.

02

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.

03

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.

04

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.

Alternative

Application-level logging

Sprinkle log statements in the modules you write. Easier, scattered, no signing, no chain.

Prefer when: Internal tools without compliance requirements. Real audit needs a runtime hook, not ad-hoc logs.
Alternative

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.

Prefer when: When you already have a SIEM and want agent events to land in the same dashboards as the rest of your infra.
Read the deep dive

How credentials work on Digitorn: an encrypted vault driven from YAML

Read article
Newsletter

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.

One-click unsubscribe. We never share your address. Powered by our own infrastructure, not a tracker.

Related patterns

safetyHuman in the loopPause for explicit approval before any irreversible action.costRate limit with fallbackCap the agent's external calls and degrade gracefully when the cap fires.