Skip to content

Build1 publisher3 min readPublished

RFC 3161 timestamps anchor an audit log's "when" outside the server that writes it

A hash chain shows that no record changed after it was written; proving when it was written is a separate question. RFC 3161 hands that question to a third party, and the stamping interval you pick sets the bill.

The Engineer · Build desk

Illustration accompanying RFC 3161 timestamps anchor an audit log's "when" outside the server that writes it

What happened

  • A dev.to write-up on RFC 3161 argues that a hash chain proves no entry was altered after writing but cannot prove when any record was created, since the whole chain could be generated later and backfilled.
  • The RFC 3161 flow sends only a digest to a Time Stamp Authority, which returns a CMS PKCS#7 token binding that hash to a timestamp under its own private key.
  • The Java sample uses Bouncy Castle with a SHA-256 digest and POSTs a DER-encoded request to the TSA with Content-Type application/timestamp-query.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure When the signing key is the only witness to time, taking the key means taking authorship of the past, and a token issued before that compromise is the single artefact the new holder cannot mint.
  • decision The stamping interval stops being a design detail and becomes a budget: it sets both the daily call count and the length of the window whose records you cannot date to anyone outside.
  • cost Stamping per record buys a third-party round trip on every write, which is affordable for key rotations and not for a general application log.
  • constraint Moving the clock offsite means your evidence later depends on a signature and a certificate you do not control, which is why the request asks the TSA to ship its cert inside the response.

The digest-only property is what makes this adoptable inside a regulated shop. You POST a hash, and the Time Stamp Authority never sees the record [6]. Nothing about your payload schema leaves the building, so the review question that usually kills a third-party integration has a short answer.

Where it costs you is call volume. Per-record stamping means one HTTPS round trip per record, sitting in the write path if you do it synchronously [20]. Head-stamping at a fixed interval collapses that, because one token anchors everything appended since the previous token [12]. Stamp every minute and you make 1,440 TSA calls a day whether you wrote a thousand records or ten million [18]. The bill for that is at the tail: records written after the most recent token have up to 60 seconds with no external anchor [19], so a crash or a rebuild-from-backup inside that window leaves those entries proved internally consistent by the chain [1], with only your own word for when they were written.

The line worth reading twice in the Java sample is `gen.setCertReq(true)`, which asks the TSA to include its certificate in the response [15]. That is what your verifier will be working from later. The published code stops one statement after it, at constructing the `TimeStampResponse`, and never validates the token [16]. Verification is the half of this integration that decides whether the archive is evidence, and it is the half the sample leaves to the reader.

On the question of whether teams are skipping this, the post offers one line: "we lost the logs for March, so we rebuilt them" is a story auditors hear more often than they should [17]. That is an anecdote about excuses, not a count of deployments, and the post puts no price on a TSA call either [21]. The argument for stamping rests on the key, not on what other teams are doing. Your chain's dates are exactly as good as the custody of the signing key, because an operator holding that key can regenerate the chain from scratch with payloads of its choosing and present the result as the original [3]. A token issued before that key was compromised holds a guarantee the new holder has no way to reproduce, short of also compromising the TSA [10].

The source states two limits on the token plainly, and both matter. It attests to a digest, not to your data, so you are still the storage system of record [9]. And it is a statement about time, not a substitute for the chain: the chain still carries the ordering and the tamper-evidence [1], while RFC 3161 supplies the external clock and the non-repudiation the chain cannot [4].

In my context, append-only audit logs where the question at review is "was this record in the set," periodic head-stamping is the right trade, which is also the author's recommendation for most systems [13]. Per-record stamping earns its round trips only where the timestamp is itself the disputed fact, and the two examples given are the right ones: a key rotation and a privilege grant [13].

What to watch

  • Whether a follow-up publishes the verify path, including token validation and TSA certificate checking, which the current sample omits.
  • A published price or rate limit from a public TSA, which would turn 1,440 calls a day into an actual line item.
  • Any adoption count, from a survey or an audit standard, for how many hash-chained logs carry timestamp tokens at all.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories