Shipping daily
Nov 1DATAAll 646 projects re-verified: 6,419 developer claims tested against registers, courts and pressNov 1DATAMalaysia TEDUH and Philippines DHSUD licence checks: expired licences and approved delays foundNov 1DATAThailand ONEP register: 2 condos found selling before environmental approvalNov 1DATAMexico PROFECO contract register checks: one sales registration belonged to a laundryNov 1DATAAbu Dhabi ADREC inspections and RAK RERA permit list added: % built straight from the regulatorNov 1SHIPPEDNew stage filter: completed but still sellingNov 1SHIPPEDPublic database page: verification levels, disclosure distribution, every marketNov 1DATA+212 projects in one day, round 3: USA, Caribbean, Gulf, Africa, Japan, AustraliaNov 1SHIPPEDStage on every case: off-plan or under constructionOct 31SHIPPEDVerification level per check on every case card: registry, independent, developer, contradicted
Changelog →

Kolaboro / Public log / Witnesses

Witnesses of the public log

A log we sign ourselves proves little if only we hold it. Witnesses are people and organisations outside Kolaboro who check every day that our log only grows, and sign what they saw with their own key. If we ever rewrote a past line, or showed one history to you and another to someone else, their signatures would stop matching.

Loading the witness list…

Registered witnesses

Loading…

The checkpoint they sign

Our log is a Merkle tree of daily lines (RFC 9162 hashing). Its signed summary, the checkpoint, is at /api/open/checkpoint in the C2SP signed-note format. The same checkpoint with every matching witness cosignature appended is at /api/x/o/checkpoint, so a client can require, say, two witnesses before it trusts an inclusion proof.

Checking the checkpoint in your browser…

Run a witness in five minutes

The witness kit is two open files, MIT licence, standard library only. It runs free on GitHub Actions in your own repository, so the check happens on machines we do not control.

  1. Copy the two files into a repository you own: kolaboro_witness.py as witness/kolaboro_witness.py, and the workflow kolaboro-witness.yml as .github/workflows/kolaboro-witness.yml. Read the script: it is about 230 lines.
  2. Make a key on your own computer: python3 kolaboro_witness.py keygen witness.key. It prints your public key and writes the private seed to a file with owner-only permissions. It never prints the private key.
  3. Store the key as a secret: in your repository, Settings, Secrets and variables, Actions, new secret KB_WITNESS_KEY with the content of witness.key. Then delete the file or keep it offline.
  4. Run it once by hand (Actions, Kolaboro log witness, Run workflow). From then on it runs every day at 08:41 UTC, after our 07:15 UTC log line.
# or anywhere with Python 3.8+
python3 kolaboro_witness.py selftest                     # RFC 8032 test vector and a cosignature round trip
KB_WITNESS_KEY=$(cat witness.key) python3 kolaboro_witness.py run \
  --name github.com/you/kolaboro-witness --state state.json --submit

What a witness checks before it signs

  • Our signature on the checkpoint, with the published log key (kolaboro-keys.json, pinned in the script).
  • That the tree did not shrink, and that an RFC 9162 consistency proof links the checkpoint it saw last time (kept in its own repository, not on our servers) to the new one. The proof is checked against the root the witness saved, never against a root we send.
  • Only then it cosigns. If any check fails it refuses to sign and the job fails, so GitHub emails its owner and the failed run, with its output, is public evidence.

Format

Cosignatures follow C2SP tlog-cosignature (Ed25519, cosignature/v1), the format used by the Go checksum database and Sigstore witnesses, so generic tools can read them.

signed message = "cosignature/v1\n" + "time " + unix_seconds + "\n" + checkpoint body (origin, size, root, extension lines)
line           = "— " + witness_name + " " + base64( key_id[4] || timestamp[8, big-endian] || ed25519_signature[64] )
key_id         = SHA-256( witness_name + "\n" + 0x04 + public_key )[0:4]

Submissions go to POST /api/x/o/witness with {"checkpoint", "cosignature", "public_key", "contact"}. The server checks the key id, the signature, that the time is within the last 48 hours, and that the size and root are exactly our tree at that size. A name is bound to the first key it is used with, a witness can never go back to a smaller tree, and names under kolaboro.com/ are reserved for our own witness. Registered witnesses and their latest cosignature: /api/x/o/witnesses.

Limits, honestly: a witness proves that everyone who checks sees the same append-only history. It does not prove a line is true; that is what the evidence, the verifier and the Bitcoin timestamps are for. Each daily line is also recorded in Sigstore Rekor. Public log · Security · Status

Protect my purchase