Get your log witnessed

Your log signs its own checkpoints, but that signature doesn't stop it from showing you one history and the next reader a different one, both signed, both verifying. A witness is an outsider who remembers the tree it signed and refuses to sign a second one. We run a witness. It's free, it cosigns anyone, and the tooling below is the same code we run.

Run a log

The only requirement we have is that you serve a c2sp.org/tlog-checkpoint note at a stable URL. If you already do, skip this section.

git clone https://github.com/MarkovianProtocol/log-server
cd log-server && pip install cryptography
python3 log_server.py --selftest && python3 log_server.py --serve
log_server.py
SQLite plus an RFC 6962 tree, serving checkpoint, tiles, inclusion and consistency proofs, and offline proof bundles.
verify_tlog_proof.py
The other side of it: bundle, leaf and policy in, PASS or FAIL out, no network.
witness_server.py
Run a witness yourself. Cosigning someone else's log costs you a few hundred lines and a small always-on process.

Send your checkpoints out

Cosignatures you never collect prove nothing, so this is the piece that actually does the work. It computes one checkpoint, submits those exact bytes to every witness, verifies each returned cosignature against that witness's pinned key before it goes anywhere near your published note, and drops anything it cannot verify.

curl -O https://raw.githubusercontent.com/MarkovianProtocol/log-server/main/submit_witnesses.py
curl -O https://raw.githubusercontent.com/MarkovianProtocol/log-server/main/witness_keys.json
python3 submit_witnesses.py

witness_keys.json carries the seven witness keys we pin, each one collected from the operator's own page rather than from any log. Submitting one checkpoint to several witnesses at once is the point — a cosignature from a witness whose key you took from the log you are checking is worth nothing.

Getting cosigned

Two routes. The first is better and does not involve us at all.

The shared list. Enroll at witness-network.org/participate. Our witness follows three of those lists hourly — testing and both staging tiers — and configures new logs on them automatically, and so do the others, so one enrollment gets you a quorum instead of one signature. It is where our own seven came from.

Or just us. Open an issue on log-server with three lines: your origin, your verifier key, and the URL your checkpoint lives at. We pin the key from your page, never from your log, and start cosigning. Public, so the record of who asked and what we did stays checkable.

The rules

Public, so a badge means the same thing everywhere:

If we lose the box

That fourth rule is, in the end, one row per log in one SQLite file: the largest tree we have signed for you. Restore that file from an older copy and the rule goes on being enforced against a mark that has quietly moved backwards. Lose the file altogether and it is worse — a witness that remembers nothing accepts anything, once, for every log at the same time.

So the row does not only live here. Once an hour the witness signs its marks — origin, size, root — into markovianprotocol.com/log, whose checkpoints seven witnesses from six operators cosign and which is anchored in Bitcoin. On start it reads the newest of those leaves back, but only from a checkpoint meeting that log's own 4-of-7 policy, and only after an RFC 9162 inclusion proof puts the leaf in that exact tree. Then it takes the higher of published and stored, per log. Upward only: a stale or replayed log can fail to raise a mark, it cannot lower one. An empty database refuses to serve rather than starting over.

The gap this leaves is the interval between publishes. Recovery returns us to the last published mark, not to where we actually were, so up to an hour of advance can reopen for a given log. Publishing more often narrows that and does not close it. Nor does any of it stop someone with root on our host from writing the file directly — nothing running on that host can. It means a rollback has to be deliberate, and leaves published evidence contradicting it. Current state is on /about, re-checked hourly.

Your badge

Type your origin. The badge renders live from our cosign table — it goes green with your tree size when we're actually signing you, and not before. The page has no say in it.

Member logs

Every log we currently stand behind, straight from the cosign table. A cosignature means the same thing for all of them; a tag says what the log itself holds, so a staging or demo instance is not read as a production one:

loading…

We watch the witnesses too

A witness that told different parties different things about the same log would go unnoticed, ours included. We poll eight witnesses hourly through the tlog-witness monitoring API and verify each cosignature against pinned keys. So far only our own witness serves that API, so there is nothing yet to compare across witnesses. Operator alerts are free — ask.

A cosignature says your history was never rewritten. It says nothing about whether your records are true.