Witnesses · checked by people who are not us
Anyone can witness a log
A signed head proves that a log's operator published it. It cannot prove that the operator never went back and rewrote an earlier entry. A witness can: each time it runs, it takes the current head, checks a consistency proof against the head it saved last time, and co-signs only if the log grew without changing anything that came before. A witness is worth something because it is not the operator, so it runs on the witness's own account, with a key only the witness holds.
What a witness does
One round, every hour
- Checks the head
- Fetches the log's signed head and checks the signature with a key it pinned the first time it saw the log.
- Checks the past
- If the log has grown, asks for a consistency proof and checks it against the root it saved itself, never one the log supplies.
- Co-signs
- Only if both hold, signs
riskrouter-evidence-cosign|v2|witness_id|tree_size|root_hash|cosigned_atwith its own key, the format in the specification, checked by both verifiers. - Raises an alarm
- If the log contradicts a head it saw (a different root for the same size, a smaller tree, a proof that fails), it keeps both signed heads, publishes them, and stops co-signing that log. The alarm is never overwritten: two heads signed by the same operator that cannot both be true are evidence the operator cannot disown.
- Cannot be driven
- Its web side only serves what it has stored: its public key, its latest cosignature of each log, and any alarm. No request makes it call a log; only its own schedule does.
A cosignature proves that someone other than the operator saw that head and checked it against every head they saw before. It says nothing about the records behind the head, and a witness that stops running proves nothing about the time after.
The registry
Every log, and everyone who witnesses one
A witness can follow the registry and witness every log it lists. The registry is a convenience, not a source of trust: a witness pins each log's keys on first sight, and if the registry later drops or changes a pinned key, the witness raises an alarm instead of taking the new one. A registry may not point a witness at a private address.
Logs
| Log | Operator | API | Head-signing keys |
|---|---|---|---|
riskrouter | RiskRouter | https://api.riskrouter.eu | dd4b4b394c95586a (published) |
Witnesses
No witnesses yet. Nobody outside RiskRouter witnesses a log in this registry today, and until someone does, a rewritten history would be caught only by a holder who kept an older head. This page lists a witness only once they publish their key somewhere under their own control.
Rendered from registry/logs.json, witnesses/ and anchors/ when this page was built.
The same data, as JSON: /registry.json.
Become a witness
Three ways to run one, each on your own account
The witness is published in the public verifier repository,
in witness/, beside the verifiers. Every way starts by making a key; the private half stays with you.
node witness/node.mjs init --out ./my-witness --name "Your organisation"
# ./my-witness/private-key.b64 secret: goes into a secret store, never into a repository
# ./my-witness/public-key.json publish it on your own site, and send it to us to be listed
- A Cloudflare Worker
- Copy
witness/wrangler.toml.example, create a KV namespace, add the key as a secret and deploy. An hourly Cron Trigger witnesses every log in the registry; the Worker serves its cosignatures at/cosignatures/<log>/latest.json. The free plan is enough. - A fork on GitHub
- Fork the verifier repository, copy
witness/github-workflow.ymlto.github/workflows/, add the key as the secretWITNESS_PRIVATE_KEY. Every hour it witnesses and commits its cosignatures towitness-state/in your fork, where anyone can read them. If it ever raises an alarm, the run fails after committing the evidence. - Your own server
node witness/node.mjs run --state ./state --every 3600 --port 8080: the same witness, storing its state in a directory and serving it read-only. Node 20 or later, no dependencies.
To be listed, send us your public-key.json, the https address where you publish the same key,
and, if you serve your cosignatures, the address of your witness. We add a file to witnesses/;
from then on a daily job collects your latest cosignature of our log, keeps it only if it verifies with your
key and ours and is consistent with our current head, and counts it here. We list nobody who has not
published their key themselves.
Cross-witnessing
Every instance can witness every other
An organisation that runs the engine itself can switch on the witness in the same stack:
docker compose --profile witness up -d. It follows the registry, so it witnesses our log and every
other listed log, and it can also witness its own. A self-hosted log whose operator publishes its keys can be
listed too, and is then witnessed by everyone who follows the registry. Each new participant makes every log
in the registry harder to rewrite unnoticed, including ours.
There is no fee, no contract and no account with us in any of this. A witness owes us nothing and we cannot switch one off.