An audit trail you cannot quietly edit
Most audit trails are a table somebody with database access can update. The distinction that matters is not whether entries are written, but whether an edited entry is detectable — and by whom.
What it is, and what it is not
A record of every write, attributed to an actor, with a before-and-after diff, chained by SHA-256 so each row commits to the content of the row before it.
It is not a log. A log is written for operators and rotated when it gets large; this is evidence, retained for the life of the tenant, because the entries an investigation needs are always the old ones.
It is also not an activity feed. A feed shows what happened recently in a form people can read; the audit trail answers who changed a field from what to what, at which revision, under whose authority — a different question with a different shape.
The mechanism: two properties
Unattributed writes are refused. Not recorded as unknown, not attributed to system — refused. The extension that enforces this sits at the data layer, so a code path that forgot to establish an actor fails loudly at development time rather than producing a row nobody can explain two years later.
That has a consequence worth stating: background jobs, imports, connector runs and agent actions all carry an actor. A nightly sync is attributed to the connector and the run; an agent action names the agent, its permission tier and the user it acted for.
Each row commits to its predecessor. The row's hash covers its own content plus the previous row's hash. Editing a row's content changes its hash, so the next row's recorded predecessor no longer matches, and verification fails at that link — naming the exact row where the chain broke.
Editing does not hide a change. It relocates the evidence from the row to the break, which is a considerably worse position for whoever edited it than leaving the row alone.
The failure it prevents
An auditor asks who approved a change eighteen months ago. The record names a person who was on another continent that week and has no memory of it.
In a system with an editable trail, there are two possible explanations and no way to distinguish them: somebody shared a login, or somebody edited the row afterwards. Both are serious, they call for different responses, and the organisation cannot tell which happened.
With a chain, one of those explanations is testable. If the chain verifies, the row was not edited and the problem is credential sharing — which points at delegation being too hard, and has a fix. If the chain breaks, that is a different and much more serious conversation, and it starts with a specific row rather than a suspicion.
How it meets the rest of the product
Every domain service writes through the same layer, so the trail covers structure edits, revisions, lifecycle transitions, approvals, permission grants, configuration promotions and connector runs without any of them opting in.
Administrators have no silent bypass. An administrator who needs into a restricted programme grants themselves access, and the grant is a row. That is the difference between an access control story that survives a review and one that ends with somebody saying nobody can tell.
Because released revisions are immutable, the trail and the object history agree by construction. A system where a released revision can be edited needs its audit trail to reconstruct history; here the history is intact and the trail records how it got that way.
Agent actions land in the same chain rather than a parallel AI log, carrying the agent, the tier, the tools called and the revisions read.
How it meets your ERP
Connector runs are attributed writes like any other, naming the connector, the run identifier and the direction. So “which system changed this value, and when” resolves to a system and a run rather than trailing off into a shrug.
That matters most on reconciliation. When Manufacturing PLM and your ERP disagree about a field, the trail on this side shows exactly when the value was last written here and by which run — which is half of the information needed to work out what happened, and frequently the half nobody has.
What the trail cannot show is what happened inside your ERP. A value edited there appears here as a difference at the next sync, not as an event, and reconstructing the other half means looking at your ERP's own audit facility.
Where the boundary is
A hash chain proves internal consistency, not external timestamping. It shows that rows have not been altered relative to each other since they were written; it does not independently prove *when* they were written to a third party. Anchoring to an external notary is a reasonable future addition and is not claimed today.
This has also not been validated against 21 CFR Part 11 or eIDAS, and we will not claim it. The foundation — authenticated acts, refused unattributed writes, a verifiable chain — is the right one, but a compliance claim on a public page is the kind of statement somebody relies on when they should not.
Facts
| Coverage | Every write — including jobs, imports, connectors and agents |
| Unattributed writes | Refused, never recorded as unknown |
| Integrity | SHA-256, each row committing to its predecessor |
| On tampering | Verification fails and names the row |
| Administrators | No silent bypass — elevation is itself a row |
| Retention | Life of the tenant, not a rolling window |
| Content | Actor, action, object at revision, before-and-after diff |
| Not claimed | External timestamping · 21 CFR Part 11 · eIDAS |
Frequently asked
Can somebody with database access edit an entry?
They can change the bytes, and doing so breaks the chain. Each row's hash covers its content plus the previous row's hash, so an edit makes the next row's recorded predecessor stop matching and verification fails at that exact link.
What happens to writes with no known actor?
They are refused, not recorded as unknown or attributed to the system. The enforcement sits at the data layer, so a code path that forgot to establish an actor fails at development time rather than producing a row nobody can explain later.
Are background jobs and syncs audited?
Yes, and they carry a real actor. A nightly sync is attributed to the connector and its run identifier; an agent action names the agent, the permission tier it ran at, and the user it was acting for. There is no anonymous category.
Do administrators bypass it?
No. An administrator who needs access to a restricted programme grants it to themselves and the grant is itself an audit row. A silent super-user bypass is convenient right up to the review where somebody asks who read a file and nobody can tell.
How long is it retained?
For the life of the tenant. A rolling retention window discards exactly the old entries an investigation turns out to need, which converts an audit trail from a usable record into a compliance artefact that satisfies a checklist and answers nothing.
Does it prove when something happened?
It proves rows have not been altered relative to each other since they were written. It does not independently prove the timestamps to a third party — that needs anchoring to an external notary, which is a reasonable future addition and is not claimed today.
Is this Part 11 compliant?
No, and we will not claim it. The foundation is right — authenticated acts, refused unattributed writes, a verifiable chain — but it has not been validated, and a compliance claim on a public page is exactly the kind of statement somebody relies on wrongly.