TILLNOTARY · OVERVIEW

Proof that history hasn't changed.

GA

TillNotary is an append-only Merkle transparency log and timestamping notary. You submit an opaque hash; you get back a signed inclusion proof and a witness-cosigned checkpoint — a receipt that this exact value existed at this exact moment, in a log whose history is tamper-evident: rewriting it breaks every proof already issued. Proofs verify on your machine against keys you pin, so you never have to take the server’s word for anything.

01What it is

A receipt, not a promise

Every entry you submit becomes a leaf in a Merkle tree that only ever grows. Appending a leaf changes the tree’s root hash; the log signs each new state as a checkpoint (origin, tree size, root hash, timestamp). When you submit, you get back three things in one response:

  • Your leaf’s position — the leaf_index in the log. An entry’s identity is (log, index), forever, and each value appears at most once per log, so the value finds its entry too.
  • An inclusion proof — a short chain of hashes showing your leaf is inside the tree with that root. See Inclusion & consistency.
  • A signed checkpoint — the log’s signature over the new state. Witnesses add their cosignatures once they have checked it, usually on their next pass; strict verification waits for the threshold you pinned. See Checkpoints & signatures.

The receipt is self-contained. Store it next to the artifact it describes and anyone can verify it later — including fully offline, with no network and no live server.

02Trust model

You never trust the server

The trust model is deliberately blunt: the server is not trusted, it is checked. Three mechanisms make that real:

  • Client-side verification against pinned keys. The CLI and SDK verify every proof and every signature locally, against public keys you pinned once (and confirmed out of band). A response that doesn’t verify is an error, not data — the SDK throws NotaryVerificationError rather than return anything a lying server produced.
  • Consistency proofs. Given two tree sizes you’ve seen, the log must prove the newer tree is an append-only superset of the older one. If any past leaf were rewritten, some consistency proof fails — and there is no rewrite that passes it. Tampering isn’t prevented by decree; it is made detectable by anyone holding an earlier head.
  • Witnesses. A witness holds its own key and cosigns a checkpoint only after verifying consistency with everything it cosigned before. New logs are cosigned by the platform witness; attach one you run, or one a party you trust runs, and require it, so no checkpoint completes without a key TillDev doesn’t hold. Presented with a rewritten history, a witness refuses to cosign and signs a refusal that anyone can check against its key. See Witnesses & refusals.
  • Mirrors. tilldev notary mirror keeps a full copy of a log and checks every entry against the signed roots. If the log ever shrinks, forks or rewrites, the mirror stops with an alarm and keeps the two conflicting signed heads as evidence. See the CLI.
Tamper-evident, precisely
No log can make tampering physically impossible, and TillNotary doesn’t claim to. The claim is tamper-evident: any rewrite of history breaks the consistency proof against every earlier head, so an honest witness refuses it and any receipt, mirror or monitor holding an earlier head detects it, with signed evidence. Detection needs someone to check: pin your witnesses, verify receipts, and keep a mirror or a heartbeat.
03At a glance

Log, witnesses, mirrors

Submitters append; the log signs; witnesses cosign or refuse; mirrors and monitors check. Checkpoints are also published in a standard signed-note format (GET /v1/logs/{slug}/note), so anyone can exchange them — two parties who compare checkpoints will catch a log that shows different histories to different people (a split view).

text
       you (submitter)
             │  POST an opaque hash
             ▼
┌──────────────────────────────┐   signed checkpoints    ┌─────────────────────┐
│  TillNotary log              │ ──────────────────────▶ │  Witnesses          │
│  append-only Merkle tree     │                         │  ours, plus yours   │
│  hybrid-signed checkpoints   │ ◀────────────────────── │  each with its key  │
└──────────────┬───────────────┘   cosignature — or a    └──────────┬──────────┘
               │                   signed REFUSAL                   │
               ▼                                                    ▼
  receipt: inclusion proof +                 mirrors and monitors re-check
  signed checkpoint                          every head; two signed heads
               │                             that disagree are the evidence
               ▼
  verified CLIENT-SIDE against keys YOU pin
  (a lying server is detected, never obeyed)

The REST surface lives at https://notary.tilldev.dev/v1 (machine-readable spec at /v1/openapi.json), with tokens shaped tnot_… and three scopes — read < submit < admin. Public logs serve reads with no token at all.

04Use it for

What to anchor

Anything whose history must be provable belongs in a transparency log. The common shapes:

Use caseWhat you submitWhat the receipt proves
Audit-chain anchoringThe rolling hash of your internal audit log, on a cadenceYour audit trail can’t be quietly rewritten after the fact — each anchor pins everything before it.
Release / build provenanceThe hash of each artifact (or its signed attestation)This exact binary existed at this time, before any incident — and was never swapped since.
Backup manifestsThe hash of every backup manifest as it’s takenA restore verifies against a manifest that provably predates the disaster.
Document timestampingThe hash of a contract, report, or datasetProof of existence at a point in time, without disclosing the document.
05Privacy

Opaque by default, public by choice

By default, a leaf is an opaque hash — 64 hex characters on a SHA-256 log, 96 on a SHA-384 log. Your content never leaves your machine, and the log reveals nothing about it: not the filename, not the size, not the type. Anyone reading the log sees only that some value was committed at some time.

When you want the content itself to be public — a signed release attestation, a published policy — you can submit raw bytes as a public attestation. That path is a deliberate double opt-in (the bytes and an explicit content_class), because those bytes become publicly readable. Details in Logs & entries.

06Cryptography

Hybrid signatures, fixed per log

Every checkpoint is hybrid-signed: a classical Ed25519 signature and a post-quantum ML-DSA signature, and both must verify. The checkpoint therefore holds as long as either algorithm survives — a break of one doesn’t forge history. A log’s suite is chosen at creation and fixed for its lifetime, so a proof from year one verifies identically in year ten.

SuiteHashSignaturesProfile
sig-ed25519-mldsa65-sha256.v1SHA-256Ed25519 + ML-DSA-65Standard — the default for most logs
sig-ed25519-mldsa87-sha384.v1SHA-384Ed25519 + ML-DSA-87Government — CNSA 2.0 algorithm levels
07Explore

What's in the box

  • Quickstart — create a log, pin trust, submit a hash, and hold a verified receipt in five minutes.
  • Logs & entries — log fields and lifecycle, the two submission modes, leaf identity, caps and freezing.
  • Inclusion & consistency — what the two proofs actually establish, how to verify them, and the heartbeat habit that catches tampering.
  • Checkpoints & signatures — the signed head, hybrid signatures, cosignatures and the signed-note format.
  • Witnesses & refusals — the platform witness, running your own, thresholds, and what a refusal means.
  • Evidence bundles — the portable file that verifies offline, and how to hand one to an auditor.
  • Service tokens — scopes, pinning a token to one log, expiry, and rate limits.
  • CLI reference and Node SDK — every command and method, with real output.

Start with the Quickstart. TillNotary is part of TillDev — one workspace, one login, one audit log.