Saphan StudioDocs
Audit and compliance

Verify a change yourself

Check one change on your own machine, with no Saphan store and no network, from three things you already trust and one folder someone hands you.

You can check that every document of one change was written by a key that chains to your organisation's owner root — on a machine that has no Saphan store and no network.

⚠ Two parts of this are not yet shipped as products. The folder is produced by a library call, not by a saphan command, and saphan-verify is not in the release packages. Until both ship, the owner's side needs engineering help to export a change, and you need the verifier built from source by someone you trust. What the check proves, once you have both, is below.

What you bring

You needWhere it comes fromWhy it must not come from the folder
The owner-root public keyThe owner, in person or over a channel you trust. It is not a secret.A folder that names its own root can name any root.
The deployment idThe owner or the consoleIt says which organisation's record you are reading.
The change id (the stream name)The person who asked you to checkIt says which change the folder claims to be about.
The bundle folderThe person who exported it—

The steps

  1. The owner's side exports the change. The export is one folder: the revocation chain and epoch history up to the newest checkpoint, the signed identity rows, the log segment and the change's documents. ⚠ There is no saphan command that writes this folder in this release; it is produced by a library call.

  2. Copy the folder to your machine by any means — a USB stick, a file share, an attachment. Nothing in it is secret, and nothing about the copy has to be trusted.

  3. Get the verifier. saphan-verify is a single program with no other part of Saphan behind it. ⚠ It is not part of the release packages, so it is built from source; compare its checksum with one the owner gave you. It opens only the folder you name; a file in the folder that links out of it is treated as missing.

  4. Run it, with absolute paths:

    saphan-verify --root /home/you/owner-root.pub --deployment 0123456789abcdef0123456789abcdef --change my-change /home/you/bundle-my-change

    --root takes the 64 hex digits of the public key, the same prefixed with ed25519:, or a file holding either.

  5. Read the answer. It says either change verified as of checkpoint <id> or not verified: <which items>. The exit status is 0 only for the first, 1 when anything is not verified, and 2 when the command could not run.

What "verified as of checkpoint X" means

  • Every document the bundle lists has an author key that chains to the root you gave, and no revocation that checkpoint X commits to disowns that key at the point it signed.
  • It is a limit, not a courtesy. What the record did after X — a key re-granted, withdrawn or retired — is not covered. A newer checkpoint covers it; ask the owner for a newer export. It does not mean the key is still good today.
  • The list of documents and the change id are the folder's own, and are not signed. The answer does not show that no required document was left out, and a fork is visible only if the bundle carries it. Ask the owner which documents the change must have, and note that the checkpoint is chosen by whoever exported the folder.
  • A seat's validity window is not judged offline; the server enforces it when the seat acts.
  • A machine certificate, where a document needs one, is carried in the folder and is not judged by this check.
  • In a Solo deployment the answer carries solo: seat-signature-only — actual execution and review are not proven.
  • Lines beginning remark: list what the command cannot tell you. Read them; they are part of the answer.
  • The verifier states that each listed document's author key chains to your root. It does not, on the strength of that document, state that the executor's seat and the reviewer's seat differ. Compare the two author keys yourself if separation of duties is your question.

When it refuses

What you seeWhat it meansWhat to do
cannot-verify: no-checkpoint-covers-itemNo person-signed checkpoint covers that document yet (a merge gate is covered only by a later checkpoint).Ask the owner to sign a newer checkpoint and export again.
cannot-verify: identity-row-bytes-missingThe folder leaves out a signed row the command needs to be sure no key was disowned.Ask for a complete export; do not accept "it is probably fine".
cannot-verify: log-segment-missingThe exported part of the log starts too late.Ask for a complete export.
cannot-verify: person-assertion-missingA checkpoint the folder carries has no stored person assertion.Ask the exporter to start the bundle after that link.
cannot-verify: machine certificate not providedThe document needs a machine co-signature and the folder has none.Ask for the certificate to be included.
refused: revocation-set-incompleteA revocation the checkpoint commits to is not in the folder, or a signed revocation is not committed.Treat the bundle as damaged or tampered; ask the owner.
refused: deployment-binding-mismatchSomething in the folder belongs to another deployment.Check the deployment id you gave; otherwise ask the owner.
fork or historicalThe record has two assertions for one checkpoint, or the document predates the epochs.Neither is a pass; ask the owner.
exit status 2The command could not run (a missing input or an unreadable folder).The message names the missing input.

Nothing the command prints turns cannot-verify, historical, fork or promise-not-applicable into a pass.

Where this sits

This is the check behind the statement on what a third party can check, and its limits are collected on the limits of the signed record. The list of checks that need no trust in the machine that produced the record is on checks you can run yourself.

On this page