Docs
Evidence pack format specification
An evidence pack is a self-contained archive for a single approved decision. It is designed
so a third party can verify the decision offline, with no Cosignet account and no dependency
on Cosignet staying online. Download one from the
for auditors page or directly at
/public/log/entries/<id>/evidence.zip.
The archive is a plain STORE-only ZIP (no compression), so every byte of every file is literally present and can be inspected with standard tools.
Files in the pack
| File | Contents |
|---|---|
bundle.json | The full decision record: entry (id, confirmation id, payload hash, credential id, signed-at, leaf hash, leaf index), credential (COSE and JWK public key), assertion (raw WebAuthn assertion), proof (Merkle inclusion proof), sth (signed tree head: root, tree size, timestamp, signature, alg), ots (OpenTimestamps proof and status), and sth_public_key. Byte-identical to the /verification endpoint. |
sth_public_key.txt | The Ed25519 public key of the tree head, base64url. Also served at /public/log/key. Pin this to check the tree-head signature. |
tree_head.ots | The raw OpenTimestamps proof for the tree head, anchoring it into Bitcoin. Omitted when the tree head has no OTS proof yet. |
verifier_node_example.js | Zero-dependency Node verifier (verifyBundle): checks the leaf, the inclusion proof, the WebAuthn signature, and the tree-head signature. |
verifier_node_example.d.ts | TypeScript type declarations for the Node verifier. |
verifier_py_example.py | Python verifier (verify_bundle): leaf and inclusion checks on the standard library; the signature step uses the cryptography package. |
run_node.mjs | Runner: loads bundle.json, calls verifyBundle, prints the result, exits 0 only on success. |
run_python.py | Runner for the Python verifier, with clear guidance if cryptography is not installed (it does not fail silently). |
README.txt | Offline verification steps and a file manifest. |
Offline verification
The signature and inclusion checks are fully offline:
node run_node.mjs
# -> { ok: true, sth_signature: 'verified' }
ok: true means the passkey signature is bound to the exact payload and the leaf
is included under the signed tree head. sth_signature: 'verified' means the tree
head was signed by the key in sth_public_key.txt. The Python path is
equivalent: python3 run_python.py.
The one online step is the Bitcoin anchor: verifying tree_head.ots
against the Bitcoin blockchain needs network access or a Bitcoin node. It is optional and
additive, and clearly separated in the README.
Stability and independence
- The verifiers are open source and vendor-independent: source. The bundled copies are byte-identical to the repository.
- A pack that verifies today keeps verifying after you leave Cosignet, the proofs do not depend on our servers.
- The pack is generated on demand and served with
no-store, so it always reflects the current record and proofs.
Related reading
- For auditors: a plain-language walkthrough.
- Verify an approval in the browser.
- DORA and all compliance mappings.