Shotoku
← Blog

How to prove what your AI agent did: a tamper-evident audit log

· By the Shotoku team

Short answer: record every decision in an append-only log where each entry includes the hash of the one before it, then sign a snapshot of the log and keep it somewhere else. The hash chain shows that a past record was changed. The signed snapshot catches what a chain misses, such as deleted entries at the end.

Why isn’t a normal log enough?

A plain log file can be edited, and nothing shows it was. That matters when you need to answer questions after the fact: what did the agent try to do, who approved it, and which rules applied at the time? If a record can change without trace, you are trusting the file, not checking it.

What should an agent audit log record?

FieldWhy it matters
WhoWhich agent made the request
WhatThe action, the resource and the amount
DecisionApproved, denied or pending
ReasonsWhich rule or limit produced that result
Human answerThe approval or denial, as a new entry that leaves the original untouched
Refused attemptsDenied requests often tell you more than approved ones

What gets caught? We tried to tamper with one

We recorded three decisions with the current npm release, signed a snapshot, then changed the files:

Changeshotoku historyshotoku snapshot verify
NoneWorksVerified
Edited the amount in record 2Error: ledger corrupt at line 2Failed: ledger corrupt at line 2
Deleted the last recordNot noticedFailed: head hash and record count don't match
Raised a limit in the policyNot checkedFailed: policy hash doesn't match

The deleted record is the one to remember. A hash chain links each record to the one before it, so nothing after the last record can vouch for it. Removing entries from the end leaves a valid, shorter chain. You need a signed record of how long the log was.

How do you set this up?

Every decision Shotoku makes already goes into a hash-chained JSONL file, one record per line, that you can read in any editor. To add snapshots, set a secret and create one:

bash
export SHOTOKU_SNAPSHOT_SECRET="a-long-random-secret"
shotoku snapshot create

Check the current files against it later:

bash
shotoku snapshot verify --snapshot shotoku.snapshot.json

Take snapshots on a schedule, such as daily, and keep them with the secret away from the machine the agent runs on. Anything recorded after your last snapshot isn’t covered yet.

What doesn’t a tamper-evident log prove?

Common questions

Do I need a blockchain for this?

No. A hash chain borrows one idea from them, and a local file plus a signed snapshot stored elsewhere covers the cases above.

Where is the log stored?

On your machine, by default in data/decisions.jsonl. Run shotoku where to see which files a directory uses.

Can I read it without Shotoku?

Yes. It is plain JSON, one object per line, so standard tools can read it. Use shotoku history for filters and integrity checks.

More in the snapshots guide.

Related