Verification runs on this device. Files are never uploaded. Trust depends
on the configured verifier key and its clock. Only this response is
authenticated.
Understanding your evidence
A saved page tells a story.
How do you prove its source?
Imagine a website publishes a statement, then removes it. You saved a
copy. The website’s owner says, “We never served that. You made it up.”
How could someone who wasn’t there tell who is right?
This is the non-repudiation problem: obtaining evidence
of what a server sent that another person can check later, rather than
having to take the person making the capture at their word.
01 · Preservation and provenance
“Unchanged” doesn’t mean “authentic.”
A hash is a digital fingerprint of a file. It helps
detect changes. A trusted timestamp can establish that those bytes
existed by a particular time. Neither, on its own, establishes who
supplied the original bytes. A fabricated page can be hashed and
timestamped just as successfully as a genuine one.
The printout-at-the-notary problem
1
You bring a printout
It might show the real page. It might have been edited in Photoshop.
→
2
You sign it before a witness
The witness observes your signature, not the website’s response.
→
3
The source is still unproven
A stamp on the printout cannot establish what the website sent.
Hashing a saved response and retaining its SSL/TLS certificate leaves
the same gap. Even if you sign or timestamp that package, you have
preserved a claim about its origin—not cryptographically established
that origin. The certificate identifies a server’s key; it is not the
server’s signature on the saved page.
Integrity: “This copy has not changed since it was recorded.”
Origin: “This server actually sent these bytes.”
A common pitfall when evaluating existing products in this space
(e.g. Hunchly, Snapoena, Page Vault, ProofSnap and GoFullPage) is assuming
that a signed or timestamped archive proves remote origin. The question
to ask is: how does the capture process rule out fabrication
before the content is hashed? That depends on the capture
architecture, not simply on whether the evidence package has a signature.
Technical detail · Why the HTTPS padlock isn’t a transferable signature
TLS authenticates the connection to its participants. Its application
records use symmetric authentication keys available to the endpoints.
A client controlling its capture environment can construct a false
transcript and authenticate it with those keys. Saving network
packets, certificates, HAR or WARC files does not by itself eliminate
that possibility.
In TLS 1.3, the server’s CertificateVerify signature covers the
handshake transcript; later application records use symmetric AEAD
protection. The distinction is explicit in the
IETF’s TLS 1.3 handshake specification
and record protection specification.
TLS 1.2 makes the corresponding separation in
RFC 5246.
For evidence reviewers · Timestamps still serve an important purpose
Preservation, timing and source authentication answer different
questions. A timestamp is useful evidence about when particular data
existed; a hash helps check whether it changed afterward. Neither
mechanism examines whether the material was fabricated before it was
submitted. See the IETF time-stamping protocol.
TLSNotary adds evidence of remote origin. It does not replace record
keeping, context or an assessment of evidentiary weight. This service’s
receipt is not a qualified electronic timestamp or a legal notarial act.
02 · A witness who doesn’t read the page
Authenticate the connection, not a printout.
TLSNotary brings an independent verifier into the cryptographic process
while the website is being contacted. The person making
the capture cannot simply substitute an invented response and convince
an honest verifier that it came from that website.
During an ArchiveBox TLSNotary capture
The source
Website
Serves a response over an authenticated, encrypted connection.
↔
Your device
Browser + extension
Uses your session and keeps the readable response locally.
↔
Independent witness
Verifier server
Checks cryptographic evidence, without reading the page.
The arrows show participation, not physical routing. This deployment
relays encrypted website traffic through the verifier’s transport proxy.
Saved on your device
response.http + receipt.json
The response, plus a small signed receipt binding it to a server name.
An independent service could always visit a public page and attest to
what it saw. The breakthrough here is checking the source without
requiring the witness to read the content. Secure multi-party
computation (MPC) and zero-knowledge proofs make that possible.
TLSNotary is a pioneer in this field, with a
published protocol dating to 2014.
Its current MPC-TLS protocol
addresses the problem without requiring websites to adopt a new signing system.
Technical detail · What MPC and zero-knowledge each contribute
MPC lets the browser and verifier perform the TLS operations together
without giving the browser unilateral control of the authentication
secrets. Zero-knowledge then lets the browser prove that a concealed
response matches a cryptographic commitment—a fingerprint locked to
those bytes—without revealing the response itself.
A zero-knowledge proof alone would not fix a transcript the client was
free to fabricate. Participation in the connection is essential.
This plugin uses TLSNotary’s MPC mode, plus a SHA-256 hash commitment;
it does not use the separate protocol called “proxy mode.” See
why an online verifier is needed
and commitment strategies.
Research context · Is TLSNotary the only approach?
No. TLSNotary has a long history, but “the first ever” and “the only
solution” are broader claims than these sources establish. For
example, the 2017 TLS-N paper
describes a different approach: extending TLS to support transferable
proofs. TLSNotary’s practical attraction is bringing a separate
verifier to existing websites while preserving the user’s privacy.
03 · Why privacy changes what is possible
Private evidence needn’t become the witness’s data.
A public archive can visit a news article itself. It cannot ordinarily
see your private social media posts, a document shared only with you,
or a page behind your login without being given access. Handing over
credentials or a readable copy can expose far more than you intended.
TLSNotary makes it possible to authenticate data from an authenticated
session while keeping its contents hidden from the verifier. That is
what makes private posts, logged-in pages and documents such as Google
Docs compelling use cases. It is a capability of the approach,
not a promise that this plugin supports every website or document.
Kept from this verifier
- Readable page contents and response headers
- Cookies, authorization headers and embedded secrets
- The URL path and query, including private document IDs
Your saved archive is still sensitive. It contains the
actual response, including any secrets the website sent in it. Someone
you give that file to can read it. The verifier at the top of this page
checks selected files locally; it does not upload them.
Technical detail · Redaction, transport and the limits of this integration
The capture configuration discloses no request transcript. It hashes
the complete received response and reveals only fixed syntax such as
HTTP/1.1, spaces and line endings. The response opening
stays local. The destination is deliberately visible to the transport
proxy; this is not an anonymity service. Cloudflare, which fronts this
deployment, can also observe transport metadata. A sensitive value
encoded in a hostname is not hidden like a value in the URL path.
TLSNotary supports selective disclosure, but this ArchiveBox receipt
binds the whole saved response. Editing or redacting that file
afterward makes this receipt fail verification. The plugin currently
authenticates a separate main-document request made by the extension,
using captured browser request headers. It does not certify all tab
traffic, downloaded assets, video content or the rendered screenshot.
A JavaScript application’s initial response may not contain the document
visible on screen.
See the extension’s disclosure model
and this plugin’s capture and server code.
04 · Read the result precisely
What does a green “Verified” result mean?
For an ArchiveBox TLSNotary receipt, it means:
These saved response bytes match a commitment signed by the configured
verifier. That verifier attests to their origin from the named server
and records its own time of issuing the receipt.
Someone cannot alter the response and retain a valid result without
defeating the cryptography or obtaining a different valid receipt.
But a valid signature identifies the signer; it cannot guarantee
the signer was honest. The trust chain matters.
The verifier operator
You trust it to run the protocol correctly, sign only successful results, protect its signing key and not collude with the person making the capture. You also trust its clock for the displayed time.
The server’s identity
You rely on TLS certificate validation and the trusted certificate authorities that bind a key to a hostname. This authenticates a domain—not a particular human author or the truth of a statement.
The checking software and key
You trust the software doing the check, the device running it, and the source of the verifier’s public key. A key supplied only by the person presenting the evidence is not an independent trust anchor.
The cryptography and its implementation
You rely on TLSNotary’s protocol, the signature and hash algorithms, and their correct implementation. This remains experimental software; a green badge is not a substitute for reviewing those assumptions.
For evidence reviewers · What this receipt does not establish
- The whole page: it covers the accompanying response, not every file in an ArchiveBox snapshot or an ArchiveWeb.page WACZ.
- The exact requested URL or account: the signed payload names the server, not the private request path, query, cookies or user identity.
- Truth or authorship: a server can publish false statements, display user-supplied text or be compromised.
- A publication date: the receipt’s time is the verifier’s issuance time, not when the website first published the content or a separately certified time.
- Automatic legal acceptance: admissibility and weight still depend on the applicable rules, context and supporting evidence.
Technical detail · Why a small receipt is enough—and what it delegates
During capture, the upstream TLSNotary verifier checks the protocol
and commitment proof. ArchiveBox’s gateway signs a payload containing
the authenticated hostname, its issuance time, the response range and
the commitment. Later verification checks that signature and opens
the commitment using your saved response. It does not replay
the interactive proof or independently repeat certificate validation.
This is an ArchiveBox receipt backed by a verifier’s attestation,
not a website-issued signature or a standalone TLSNotary presentation.
A dishonest operator, a compromised signing key or collusion could
produce a false receipt that passes the local check. Running your own
verifier gives you operational control, but does not make your
self-issued receipts independent evidence to someone who distrusts you.
See TLSNotary’s explanation of delegated trust.
05 · Evidence you can check elsewhere
Keep the response. Keep the receipt. Know the key.
response.httpThe original response bytes, stored once. This is the content being authenticated.
+
receipt.jsonThe signed commitment and its opening. A small receipt, not another copy of the page.
You do not need this public service to stay online to check an existing
capture. Preserve both files unchanged, the verification software, and
an independently obtained copy of the verifier’s public key. You can
give those to another reviewer to check on their own device.
Developer instructions · Verify locally with Node.js
Review and obtain verify.mjs from the source repository.
Place it alongside the two capture files. With a current Node.js
version supporting Web Crypto and DecompressionStream,
run the command below from that directory. Replace the placeholder
with the base64 SPKI public key you independently trust for the
verifier that issued the receipt.
TRUSTED_KEY='INDEPENDENTLY_TRUSTED_BASE64_SPKI_KEY' node --input-type=module <<'JS'
import { readFileSync } from 'node:fs';
import { verifyReceipt } from './verify.mjs';
const receipt = JSON.parse(readFileSync('receipt.json', 'utf8'));
const response = new Uint8Array(readFileSync('response.http'));
const result = await verifyReceipt(receipt, response, process.env.TRUSTED_KEY);
console.log('Verified:', result.server_name);
console.log('Verifier time:', new Date(result.time * 1000).toISOString());
console.log('Authenticated bytes:', response.length);
JS
The check validates an Ed25519 signature over the decoded payload,
recomputes SHA-256(response.http bytes || 16-byte blinder),
matches the signed byte range and requires a complete successful HTTP
response. The blinder is random data that hides the commitment from
guessing while the response is private. It is saved locally in the receipt.
A green result on a website controlled by an untrusted party is not
independent verification. For contested evidence, review the code and
establish the key through a separate trusted channel. Keep the original
key when an operator rotates keys; newly published keys do not
automatically authenticate older receipts.
Want to operate a verifier? The plugin includes
Docker Compose, example configuration and setup instructions.
Captures are opt-in because the cryptographic work adds time and bandwidth.