Audit logs for AI agents: what to log, why hash chains, and why “we log everything” is not an answer
The seven fields an agent audit log entry needs, how a hash chain makes edits detectable, the two things it does not prove, and retention as a written policy.
Last updated
6 minute read · Written by the team that builds UtilitySpaces. More about UtilitySpaces.
An audit log for an AI agent is an append-only record of every action the agent took: which agent, on whose behalf, called which tool with which arguments, what came back, and who approved it. It exists so that a claim about what happened can be checked against evidence rather than against the agent’s own account of itself.
We build UtilitySpaces, and the audit log is the part of the product we are asked about most by the people whose job is to say no. This piece is what we tell them, including the two things a hash chain does not prove.
What must an entry contain?
Enough to reconstruct the action without trusting anyone’s memory of it. In practice that is seven fields, and an entry missing any one of them will fail you on the day you need it.
| Field | Why it is there | What goes wrong without it |
|---|---|---|
| Actor | Which agent, and which person or schedule it was acting for | “The AI did it” is the whole answer, and it is not one |
| Tool | The named operation, on which connected app | You know something happened in the CRM but not what kind of thing |
| Arguments | What the agent actually sent: the record, the fields, the recipient | You cannot tell a correct call from a wrong one with the right name |
| Result | What the app returned, including failure | A failed write looks identical to a successful one |
| Decision | Who approved or rejected, when, and what they were shown | Approval becomes an assertion rather than an event |
| Timestamp | When, in a form that does not change on the way back out of storage | Ordering disputes you cannot settle |
| Sequence number | A monotonic counter per workspace | A gap is invisible; you cannot say “entry 412 is missing” |
The arguments row is the one most products skip, usually because the payload is large or contains personal data. Skipping it turns the log into a list of verbs with no objects.
In UtilitySpaces an entry carries a title, a note, an optional code, an actor and a small key-value data bag, and approval decisions are written into the same chain as the actions they authorised, so the question “who agreed to this?” has the same kind of answer as “what was done?” The approval side of that is described on the approvals page.
Why is “we log everything” not an answer?
Because it describes volume, not properties. A log can be complete and still editable, or tamper-evident and still missing the one field you need, or both of those and kept for a week. “Everything” says nothing about whether the entries can be changed after the fact, whether gaps are detectable, whether arguments are recorded, or how long it is all kept.
The three questions to ask any vendor, including us, are narrower. Can an entry be edited or deleted after it is written, and if someone does, how would you know? Does each entry record what was sent and what came back, or only that a call happened? And is an approval a row in the same log as the action, or a status flag somewhere else that usually agrees with it?
A vendor who answers the first with “only administrators can edit it” has told you the log is editable. That is not a security failing on its own; it is a property you should know before relying on the log as evidence.
What does a hash chain actually do?
It makes editing detectable. Each entry stores a digest of its own contents, computed with SHA-256, and also the digest of the entry before it. Change any entry after the fact and its digest no longer matches; delete one and the next entry points at a predecessor that is not there. Either way, a verification pass walking the chain stops at a specific sequence number and reports it.
Think of it as a stack of numbered pages where each page begins by quoting a fingerprint of the page before. You cannot pull page 40 out, or rewrite it, without page 41 noticing, and you cannot fix page 41 without page 42 noticing, all the way to the end. An ordinary hash chain, nothing exotic.
Two details decide whether it holds in practice. Appends have to be serialised, so two writers cannot fork the chain into two plausible histories; UtilitySpaces takes a per-workspace lock on every append for that reason. And the timestamp has to be hashed in exactly the form the database hands back on read, or verification recomputes a different digest and reports tampering that never happened. A chain that cries wolf is ignored the way any noisy alarm is.
What does a hash chain not prove?
Completeness, and truth. A chain proves nobody edited the log after it was written. It does not prove every action wrote an entry. A code path that forgot to log, or a component outside the workspace, leaves a chain that verifies perfectly and says nothing about it. Integrity is a property of the chain; completeness is a coverage question re-answered every time someone adds a code path.
Nor does it prove an entry was correct, only that it is what was written at the time. If the agent recorded a misleading note, the chain faithfully preserves the misleading note. This is why the arguments and result fields matter more than the note: they are what the system sent and received, not what the model said about it.
What do you do when the log disagrees with the agent’s summary?
Believe the log. The summary is model output; the log is what the tool calls were. When an agent reports “updated three contacts” and the log shows two writes and one failed call, the agent is wrong about its own work, and that is common enough that you should expect it rather than be surprised by it.
Then treat the disagreement as a signal about the job description, not a one-off. Read the arguments on the entries in question. If the agent sent the right calls and summarised badly, tighten the role text so the report is a list of sequence numbers rather than prose. If it sent the wrong calls, the tool set or the boundary was too wide, and the fix belongs in the agent’s configuration, not in a stern instruction to be more careful.
And if the log disagrees with itself, meaning verification breaks at a sequence number, that is the one outcome you should never explain away. Stop the schedule that writes there, note the number, and write to security@utilityspaces.com before anything else.
How long should the log be kept?
At least as long as the decisions it explains can be questioned. A refund can be disputed months later; a contact created in the CRM can be the subject of a data request long after that. The log is the only artefact that answers either question with a sequence number instead of a recollection, so its retention should be set by the longest such window you face, not by storage cost.
Two practical rules. Retention is a written policy, not a default you discovered; decide it and tell the people who will ask. And export before you delete: if policy says a year, the year-old entries should leave in a form you can still verify, not vanish. Ask support@utilityspaces.com for the current retention terms on a UtilitySpaces workspace before you rely on them; we would rather state them in an email than have a number on a blog post drift.
Where does the log stop being useful?
Limits, stated plainly. The UtilitySpaces log records what agents did through the workspace; it does not see what happens inside a connected app afterwards, so the app’s own audit trail is still the record of that. The chain proves integrity, not completeness. There is no third-party security certification behind any of this, and a procurement process that needs one cannot be satisfied here today. What we do have is described on the security page.
What the log is for is duller than catching an insider: six months from now somebody asks why an agent did a thing, and the answer should be an entry, not a meeting. The wider design that puts approvals and actions in one chain is in what is an agentic workspace. If you would rather see the entries than read about them, the demo workspace lasts exactly sixty minutes from creation, long enough to run one agent and walk its chain. Start a demo workspace.