Check a Provlyn access log yourself

Every day a vault has activity, Provlyn hashes that day's entries together, folds in the hash of the vault's previous sealed day, and has the result timestamped by a qualified trust service provider. So the newest seal depends on every one before it. This page gives the exact recipe, so you can rebuild each day from the entries and confirm it produces the hash that was timestamped, without asking Provlyn.

What you need

The vault's evidence file: its owner downloads it from the access log (“Download evidence file”). It holds every entry exactly as stored, and every seal with its timestamp token. To check a token, any RFC 3161 validator, or provlyn.com/validate-timestamp.

Rebuilding one day

  1. Take the vault's entries in order: by created_at, then by id, each compared character by character.
  2. Choose the entries the day covers: those whose created_at begins with the day's date (YYYY-MM-DD). From version 6, add the vault's seal entries dated after its previous sealed day and before this one.
  3. If the day was sealed part-way through, its seal covers only the first entries of that day — the number the seal records.
  4. Build the text for the day's version (table below), take its SHA-256, and compare it, as hexadecimal, with the seal's combined hash.
  5. The seal's token timestamps the 32 bytes of that hash. A validator shows the hash it covers and when.

Check an evidence file here

Choose the vault's evidence file. It is read and checked in your browser; nothing is sent to Provlyn.

Writing an entry as a line (version 2 onwards)

The version's fields in the order listed, joined by |. A missing value is written as nothing. created_at and accessed_at are written as ISO 8601 UTC with milliseconds, for example 2026-10-07T13:47:25.933Z, whatever form they are stored in. Any |, carriage return or line feed inside a value is replaced by a space. Lines are joined by line feeds.

The versions

VersionRuleFields, in orderHow it was established
1 (recovered)The day’s entry ids in order, joined by commas. Combined hash: SHA-256 of vault id | day | ids.id onlyRecovered on 24 September 2026 from the work that built it on 25 August 2026, after the code that made it had been replaced. Proven by rebuilding sealed days exactly, on staging and on 38 of production’s 40 version 1 and 2 days; the other two belong to deal rooms since deleted, whose entries no longer exist.
2 (recovered)Each entry as one line of the version 3 fields. Combined hash: SHA-256 of vault id | day | lines.id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_emailRecovered on 24 September 2026 from the work that built it on 4 September 2026. Proven the same way as version 1.
3As version 2, with the vault’s previous sealed day folded in. Combined hash: SHA-256 of vault id | day | previous hash | lines. A vault’s first chained day uses an empty previous hash.id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_emailThe code that sealed these days.
4As version 3; each line adds s3_key and accessed_at.id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_email, s3_key, accessed_atThe code that sealed these days.
5As version 4; each line adds via_kind, file_id, file_name, page, seconds and detail.id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_email, s3_key, accessed_at, via_kind, file_id, file_name, page, seconds, detailThe code that sealed these days.
6The same fields and formatting as version 5. What differs is which entries a day covers: its own entries, plus the vault’s seal entries (action log_sealed) dated after its previous sealed day and before this one. A day holding only seal entries is not sealed on its own, so its seal entries are covered by the vault’s next day with other activity.id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_email, s3_key, accessed_at, via_kind, file_id, file_name, page, seconds, detailThe code that sealed these days.
7As version 6; each line adds ip_source, where the IP address came from: cloudflare (the network that received the request), forwarded (the forwarding header added by Render's proxy, used when the network's own is missing; the sender cannot set it), unknown (no usable address), or storage_record (Amazon's storage record).id, vault_id, user_id, action, ip_address, created_at, shared_token, accessor_type, user_agent, viewer_email, s3_key, accessed_at, via_kind, file_id, file_name, page, seconds, detail, ip_sourceThe code that sealed these days.

Days that cannot be rebuilt

A seal is Provlyn's record that a day was sealed, and it is kept when the entries are not. When an account or deal room is deleted, its entries go with it, so its seals can no longer be rebuilt. Two days sealed on 20 May 2026 are in this position.

What a seal does not prove

A seal proves that a day's entries are exactly as they were recorded. It does not prove that what was recorded was correct. One case is known. Before 07:30:00 UTC on 24 September 2026, the IP address in each entry was taken from a part of the request that whoever made it could set. Browsers do not set it, so most of those addresses are the visitor's own, but an address recorded before that time cannot be relied on to show who made a request. From 07:30:00 UTC on 24 September 2026 at the latest, the address is the one the network that received the request saw, which the sender cannot set. Sealed entries are never changed, so the earlier addresses remain as they were recorded.

Recovered versions

Versions 1 and 2 were not kept in the code that made them. They were recovered on 24 September 2026 from the work that built them and proven by rebuilding sealed days exactly. Versions 3 onwards are the code that sealed their days. Every version is frozen: a day always rebuilds with the version it was sealed under.