What a hash-chained audit ledger actually proves
And what it does not. A plain-language walk through the chain for the person who has to sign off.
At some point a vendor tells you their audit log is “tamper-proof”. You are the one who has to sign the BAA, or the vendor risk assessment, or the incident report a year from now. So it is worth knowing what a hash chain proves, what it does not, and how to check.
The mechanism in one paragraph
DialSplice writes every action it takes to an append-only ledger. A claim, a preflight evaluation, a disposition, a configuration activation, a denied read. Each row records the event, the actor, the scope (organization and location), a timestamp, and a hash. The hash is SHA-256 over the row’s content plus the hash of the previous row. That last part is the chain. Row 200’s hash depends on row 199’s hash, which depends on row 198’s, all the way back to the first.
What that proves
Nothing in the past was changed. If anyone edits row 150, its content no longer matches its hash. Even if they recompute row 150’s hash, row 151 embedded the old value, so row 151 no longer verifies. Every row after the edit breaks. A verifier that walks the chain finds the break.
Nothing was removed. Deleting row 150 leaves row 151 pointing at a hash that no longer exists in the sequence. The gap is visible.
Nothing was reordered. Swapping two rows changes which previous hash each one embeds. The chain no longer resolves.
Put together: changed, missing, or reordered history is detectable. That is the exact claim, and we make it in those words on purpose. It is not “impossible”. It is “detectable”, which is what an auditor actually needs, because detection is what you can demonstrate.
What it does not prove
It does not prove the event was true. A hash chain proves the row was written as it stands and has not been altered since. It does not verify that M. Ortiz really set the disposition “Booked”. That guarantee comes from the layer above the ledger: runtime-validated access policy, scope on every request, credentials that never reach the browser. The ledger records what the system did under those controls. If the controls are weak, the ledger faithfully records weak behaviour.
It does not prove the future. A chain verified today says nothing about rows added tomorrow. Verification is a thing you do, not a thing you have. Ask when the chain is verified and who can see the result. In the DialSplice workspace the ledger header reads “Append-only · chain verified” because verification runs, not because the words are decorative.
It does not store what was said. This is a feature, and you should confirm it. The DialSplice ledger stores events and hashes, not message bodies, transcripts, or recordings. A row like sms.send records that a send was attempted, by whom, in which scope, and what the provider returned. It does not record the text. If a vendor’s “audit log” contains the content of the conversation, you are signing for a second copy of regulated content, and the hash chain does not make that copy smaller.
It does not replace the ledger’s own protection. Append-only is enforced by the service, not by the arithmetic. The hash chain lets you catch tampering; it does not prevent someone with write access from trying. Ask what prevents deletion at the storage layer and who holds that access.
Reading a real sequence
Here is the kind of sequence the Security page shows as an exhibit, with the hashes truncated:
callback.claimed· M. Ortiz · Northgate · 7b02…9d4apreflight.evaluated· policy · Northgate · a3f9…c21ecall.disposition.set· M. Ortiz · Northgate · e51c…08b7contact.read· A. Patel · Northgate → Riverside · 4d77…f130 · Denied · cross-clinic scopesms.send· R. Okafor · Cedar Park · 18ab…d7c3 · Reconciliation · provider outcome unknownconfig.activated · rev 14· admin · organization · c9e0…5a62
Three things to notice. The actor “policy” on the preflight row means the system evaluated consent, quiet hours, and caps, and that evaluation is itself a logged event. The denied read is on the ledger: a scope failure is recorded exactly like a success, which is how you prove that fail-closed actually fails closed. And the reconciliation row shows that an ambiguous provider outcome was held rather than retried; the ledger does not pretend to know something the provider did not say.
The last row is worth a second look. A configuration activation sits in the same chain as an agent’s disposition. When someone asks what the quiet-hours rule was on a given afternoon, the answer is a revision number, and the row that activated it is a few hundred rows back, hashed like everything else.
How to check
You do not need to trust a screenshot. Ask for an export of a range of rows with their hashes and previous-hash fields, and recompute. SHA-256 is a standard function; any engineer on your team can walk a few hundred rows in an afternoon. If the chain resolves, the mechanism is real. If the vendor cannot give you the fields to do that, the word “tamper-proof” was a claim, not a control.
We will walk your security or compliance lead through the architecture, the ledger, and the data classes before you sign. Bring the questions below.
What to ask your vendor
- What exactly is hashed in each row, and does the hash include the previous row’s hash?
- Does the log contain message bodies, transcripts, or recordings? If yes, why?
- Who can write to the ledger, and what stops a delete at the storage layer?
- When does chain verification run, and where do I see the result?
- Can I export rows and recompute the chain myself?
See your stack, spliced.
Bring the names of your phone system, CRM, and system of record; we'll show you the workspace your agents would use.