Seal the next passport version
Response
Versions, not overwrites
Every call mints the next version — a dated snapshot, never a mutation of an earlier one. Sealing after two more documents complete gives you v2 alongside v1; both remain verifiable forever. This is deliberate: an evidence artifact that can be silently replaced is not evidence.- Versions are numbered per room, starting at 1.
- Quota: 20 versions per room.
- The room’s public view and
GET /api/rooms/{roomCode}always point at the latest version; older versions stay reachable by their own verify codes.
The canonical manifest
The manifest is JSON serialized canonically — sorted object keys, no insignificant whitespace, UTF-8, invariant culture, lowercase hex hashes — so the same facts always produce byte-identical output and therefore the same SHA-256. Determinism is the whole point: it is what makes the hash, and the chain built on it, meaningful. The manifest has three parts:Manifest structure (illustrative)
documents array:
- Hash fields appear only when the artifact exists. A document with no sealed artifact simply has no
sealedSha256key — the manifest never pads absence with placeholders. statusAtSnapshotis a labeled attestation, not evidence. It records what our systems said at snapshot time. The hashes are independently verifiable; the status is our word, and the manifest says so.
coverage block enumerates what the passport does and does not speak to. It is rendered verbatim on the public verify page — the artifact carries its own limits.
The hash chain
Each version’s manifest embedsprevManifestSha256 — the SHA-256 of the previous version’s manifest (null for v1). That forms a per-room chain:
Chain
chainOk. The verdict is never a stored flag; it is earned on every view.
The sealed artifact
Alongside the manifest, each version produces a Closing Passport certificate PDF: the room header, the version and chain line, a per-document hash table, the coverage statement, and the manifest SHA-256. The PDF is sealed with the same Google Cloud KMS signature that seals first-party orders — the private key never leaves KMS — so it verifies in any standard PDF signature viewer on its own, offline, with no SignSealShip involvement.Verifying a passport
Every version has a public verification page:Verify page
Verify over the API
Response
Re-hash the manifest
Re-canonicalize the returned manifest (sorted keys, no whitespace, UTF-8) and SHA-256 it. It must equal
manifestSha256.Walk the chain
Fetch the prior version by its verify code and confirm its
manifestSha256 equals this version’s prevManifestSha256.Check the sealed PDF
Download the PDF from
downloadUrl, confirm its SHA-256 equals sealedSha256, and open it in a PDF signature viewer to validate the KMS signature independently.None of these steps require trusting SignSealShip. The artifact proves itself.
Honest coverage — what a passport does not say
A Closing Passport is strong evidence with stated limits, and the limits are part of the artifact:- Statuses are attestation.
statusAtSnapshotvalues are our records at snapshot time, explicitly labeled as not being independent evidence. - No payment claims. The passport says nothing about whether anyone was paid.
- No delivery claims unless a delivered shipment’s hash is actually on record.
- Nothing about absent documents. A document never attached to the room is simply outside the passport’s world — the coverage statement says so.
The verify code is a bearer credential for the passport, like the room link is for the room. Unknown or malformed codes return an identical generic not-found response, so codes cannot be enumerated.
Related
Passports API reference
Full request and response shapes for sealing and verifying Closing Passports.
Evidence model
The locked vocabulary behind SEALED and RECORDED, and what each cryptographically means.