← Back to Field notes
WINROVE / Engineering: audit chain

How Winrove writes an audit chain that survives a freedom-of-information request.

A per-event SHA-256 chain, anchored daily to a public timestamping service, that an examiner can verify without Winrove's cooperation.

May 9, 2026 · Winrove Team

Cover illustration for How Winrove writes an audit chain that survives a freedom-of-information request.

What an audit chain is for

A federal contracting officer submits a Freedom of Information Act request for all onboarding records related to a specific contract vehicle. The request lands on a Friday afternoon. By Monday, your compliance team needs to produce a complete, tamper-evident record of every I-9 attestation, every offer-letter countersignature, and every clearance-related document event for the affected personnel. If your onboarding system produces a flat database export, you have a problem: the examiner has no way to know whether the log was edited between the triggering event and the export. A chain solves that problem. A log does not.

An audit chain is a tamper-evident record of the events that produced a regulated artifact. For an I-9 it answers: who attested to what, when, under what authority, and whether the record has been touched since. For a clearance event it answers: which adjudicator letter landed in which inbox at which timestamp, and whether that letter is the same file that exists in storage today. Most onboarding software produces an audit log, which is a database table of events. A log is helpful but does not survive a hostile reader, because the writer can edit it after the fact. The chain part of an audit chain is what makes the record provable, not just present.

The shape of the record

Every event in the chain is a small structured object: who, verb, what, when, prev-hash. Winrove computes a SHA-256 digest of the event body and writes the result into the next event's prev-hash field. The first event of a tenant uses a tenant-genesis hash derived from the tenant's own onboarding event, so the chain is rooted in a publicly anchored timestamp from day one.

event {
  tenant:  meridian-federal,
  ts:      2026-05-15T09:42:11Z,
  actor:   T. Bramwell (user:bram_117),
  verb:    countersigned,
  object:  I9.section2 (case:dni-okafor),
  body:    sha256(<artifact bytes>),
  prev:    0x7a1e8b8e1a204cb31ed7f6018c2e44a3107e1,
}
hash(event) -> 0x7a1f3c402d18b9c0f4e218cf6f5a90712bc4e

Three things the structure enforces

  • The artifact is not in the event. Only its SHA-256 hash is. The artifact itself lives in object storage. The chain proves the artifact existed at a specific point in time and was not altered afterward. If someone replaces the PDF in storage, the hash in the chain will no longer match, and the discrepancy is immediately visible during replay.
  • The actor is an identity reference, not a name string. The chain records the user record identifier, not the human's display name. If a contractor legally changes their name, or if a role assignment changes, the audit chain still resolves correctly. The identity record carries the history; the chain carries the pointer.
  • The chain is per-tenant. Events from one contractor organization cannot bleed into another tenant's chain. Cross-tenant aggregation would require a Merkle tree of per-tenant chain heads, which Winrove does not need at current scale. Per-tenant isolation also simplifies FOIA responses: the export scope is unambiguous.

Why deterministic serialization matters

A hash is only reproducible if the input bytes are identical every time. JSON is notoriously non-deterministic: key ordering, whitespace, and Unicode normalization all affect the byte sequence. Winrove uses a canonical serialization format (sorted keys, no insignificant whitespace, UTF-8 NFC) applied before hashing. This is not optional. During development, an indexing migration changed the default key ordering for one event type. Replay verification caught the mismatch immediately. The fix was a one-line serialization correction, a re-anchor, and a postmortem note. Without deterministic serialization, that bug would have silently broken the chain for every event of that type going forward, and no one would have known until an examiner ran verification against a production export.

Anchoring the chain to an external witness

A chain that lives entirely inside Winrove is not useful to a reader who does not trust Winrove. The chain proves internal consistency, but it does not prove that the chain itself was not reconstructed wholesale after the fact. External anchoring solves this.

Every 24 hours, Winrove publishes the current chain head hash to a public timestamping service that the company does not operate. The anchor is the chain head's hash, timestamped by a third party under no obligation to Winrove. The anchor URL is included in every audit bundle export.

An examiner can verify the chain without Winrove being online or cooperative: fetch the anchor from the timestamping service, walk backward through the chain events, recompute each hash, and confirm every link matches. The verification script included in the export bundle is dependency-free except for SHA-256, which is available in the standard library of every platform a federal examiner is likely to use (Python, Go, PowerShell, OpenSSL on Linux).

Replay verification as a continuous control

Anchoring proves the chain head at a point in time. Replay verification proves the chain is internally consistent from genesis to head. These are different assurances and both are necessary.

On every audit export, Winrove runs a full replay-verification pass before sealing the bundle. The process walks the chain from genesis to the current head, recomputes each event hash from its serialized body, and confirms each hash matches the prev-hash stored in the following event. If any hash mismatches, the export aborts and the operator receives an alert. No partial or potentially corrupted bundle is delivered to an examiner.

Replay also runs on a scheduled cadence for every active tenant: once per day for tenants with recent activity, weekly for quiescent ones. Each replay run is itself recorded as an audit event in the chain, which means the history of chain-integrity checks is itself part of the tamper-evident record. An examiner reviewing the bundle can see not just the business events but the full history of when the chain was verified and by what process.

What happens when replay fails

A replay failure in a production tenant is treated as a P1 incident. The tenant's export capability is suspended until the failure is diagnosed and resolved. The failure event, the diagnosis, and the remediation are all recorded as chain events before export capability is restored. This means an examiner will always see the full picture, including any integrity incidents, rather than a sanitized record.

What an examiner actually receives

When a customer exports an audit bundle in response to a FOIA request, an OIG inquiry, a DCSA review, or an internal investigation, the bundle contains four components:

  1. Every event in the tenant's chain for the requested time window, in canonical serialized form.
  2. The referenced artifacts (I-9 PDFs, signed offer letters, countersigned contractor agreements, E-Verify case confirmation pages) that the events reference, with their stored SHA-256 hashes.
  3. The daily anchor records that span the export window, including the external timestamping service URLs where each anchor can be independently confirmed.
  4. An offline verification script the examiner can run without any Winrove account, API key, or network connection to Winrove infrastructure.

The two-pass verification process an examiner runs is straightforward. First pass: hash each event body using the same canonical serialization, confirm the computed hash matches the prev-hash in the next event, and confirm the chain is unbroken from genesis to head. Second pass: confirm the chain head hash appears in the expected daily anchor at the timestamping service. If both passes succeed, the examiner has verified the record without Winrove being a trusted party in the process at all.

That independence is the point. A FOIA examiner, an OIG auditor, or a DCSA investigator should not have to take Winrove's word for anything. The chain is designed so they do not have to.

Practical takeaway

If your onboarding system cannot answer the question "prove this record has not changed since it was created" without asking you to trust the vendor, you have a log, not a chain. For federal contractors handling I-9 records, clearance events, and ESIGN-governed offer letters, the difference matters the moment a formal records request arrives. Winrove is a product of IT Custom Solution LLC, live at winrove.com. If you want to see a sample audit bundle before a real request forces the question, that is the place to start.

Preserved Field Notes article. Original path /blog/audit-chain/. No unrelated help guide has been substituted.

Related Field notes

Browse the Field notes index.