Evidence chain and audit log
“Tamper-proof” is a common word in product descriptions and rarely a checkable claim. A log whose integrity only the vendor can confirm is of little help under scrutiny.
SentryMail therefore links every audit entry to the hash of its predecessor — and ships a standalone verification tool that works without SentryMail. Both belong to the Open Core version.
How the chain works
Section titled “How the chain works”Every entry in the audit log carries three additional fields:
| Field | Meaning |
|---|---|
seq |
gap-free ascending position |
prev_hash |
hash of the predecessor (64 zeros for the first entry) |
entry_hash |
SHA-256 over its own content including prev_hash |
It follows that:
- A changed entry no longer matches its
entry_hash. - A removed entry leaves a gap in
seqand a broken reference in its successor. - Swapped entries break the linkage even if both are individually unchanged.
Repairing this retroactively would require recomputing all subsequent entries — which shows up at the latest when comparing against a package exported earlier.
Checking the state
Section titled “Checking the state”Under Settings → Activity the chain state is shown: the number of entries and whether the chain is intact. A break is named with the affected position, without having to export anything first.
Exporting an evidence package
Section titled “Exporting an evidence package”Same place: Export evidence package, or via the API GET /audit-events/evidence-package. The ZIP contains:
| File | Content |
|---|---|
events.jsonl |
one entry per line, with hashes |
manifest.json |
chain head, entry count, algorithm, format version, export time |
README.md |
verification instructions, bilingual |
Administrators and the data protection officer have access — their oversight role is worthless without independently verifiable evidence.
Verifying independently
Section titled “Verifying independently”The tool lives in the source tree at tools/sentrymail-verify/verify.py:
python verify.py sentrymail-nachweis-20260726-120000.zippython verify.py --lang en package.zip| Exit code | Meaning |
|---|---|
0 |
chain intact |
1 |
break found — details on the output |
2 |
package unreadable or format unknown |
A package with a newer format version is refused (exit 2), not declared broken. A false assurance would be worse than none.
Retention and the chain
Section titled “Retention and the chain”The chain does not override any deletion obligation. Where a retention period applies, it takes precedence — but it need not destroy the chain.
The content is deleted; position, timestamp and linkage remain. The entry stays as a tombstone: it remains provable that and when something happened, without keeping personal data beyond the retention period. The verifier does not recompute the content hash for tombstones — it cannot match any more, and it should not.
Deleting the rows instead would create a gap, which the verifier would rightly report as a break.
Third-party timestamps (Enterprise)
Section titled “Third-party timestamps (Enterprise)”The chain proves that entries are unchanged relative to one another. It does not prove when they came into being — the timestamps within come from the server itself, and whoever controls the server controls the clock.
A timestamping service per RFC 3161 closes that gap: it confirms that a particular chain head already existed at a particular point in time. Under Settings → Timestamping service the operator enters the URL of their service — commercial, governmental or self-hosted. No vendor is hard-wired into the code. Without configuration the feature is simply absent.
Stamping happens at a configurable interval (default daily) and on demand before an audit.
A failed stamp is recorded as an anchor with status failed rather than swallowed: a gap in the anchor sequence is itself a statement, and the operator should see that their service is not responding.
Auditor access (Enterprise)
Section titled “Auditor access (Enterprise)”An external auditor needs sight of the audit log, but no account with administrative rights and no permanent access. Under Settings → Auditor access a grant is issued:
- time-limited — the expiry date is mandatory
- read-only — there is no writing endpoint
- separately logged — who looked at what and when goes into the chain in turn
Revoking does not delete the grant but marks it: that access existed is itself part of the evidence. Privacy mode continues to apply — an auditor sees the audit log, not evaluations of individual people.
Relation to NIS2 and BSI
Section titled “Relation to NIS2 and BSI”The chain provides the technical basis for demonstrating that logs were not altered afterwards — a recurring audit point under ISO 27001 and the BSI IT-Grundschutz. It replaces no legal assessment and says nothing about whether your retention concept is complete. See also the compliance mapping.
The Enterprise building blocks above — third-party timestamps and time-limited auditor access — close the two gaps a pure hash chain leaves open: the point in time towards third parties, and inspection without administrative rights.
SentryMail is a registered trademark of SecureBits Cyber Security UG