The evidence bundle¶
Every verdict produces a small, layered record under attestations/. Each layer
answers a different "how do I know?" — and every layer is checkable offline, from
the repository, with only a public key.
flowchart LR
V[verdict] --> E[signed<br/>envelope]
V --> D[DSSE<br/>in-toto]
V --> W[witness<br/>cosignature]
V --> T[tlog<br/>inclusion proof]
E & D & W & T --> B[[one offline-<br/>verifiable bundle]]
1 · The signed verdict¶
The agent signs the verdict into an action envelope. Two properties make it evidence rather than decoration:
- Tamper-evident — the signature is over the canonical verdict, so mutating any field breaks it.
- Wrong-key-proof — it verifies only against the agent's public key; no other key can pass off a signature.
The receipt is also self-describing: alongside the signature, recurve records the signer's identifier and a link to the verifiable envelope directly on the receipt (not in a sidecar), and — because the signer runs after the receipt hash is fixed — those annotations are excluded from the hash, so the chain still verifies.
2 · A DSSE in-toto attestation¶
The same verdict is emitted as a DSSE-wrapped in-toto Statement under a
recurve.dev/verdict/v1 predicate — the standard attestation format the
supply-chain ecosystem already consumes. The signature is over the DSSE
pre-authentication encoding, so it commits to the exact payload bytes, not to a
malleable JSON rendering. A tampered or forged envelope is rejected.
3 · An independent witness cosignature¶
This is the structural-neutrality pillar, made literal. A second, distinct agent counter-signs every verdict. Verification requires all of:
- the signer's envelope verifies under the signer key;
- the witness's cosignature verifies under the witness key;
- the witness identity differs from the signer's — the whole point;
- the cosignature vouches for this signer over this verdict.
The bundle is complete, not merely present: a verdict signed but not independently witnessed fails closed. So the referee cannot quietly bless its own output — a second party has to vouch for each result.
Independence in practice
The signer and the witness are distinct keys with distinct identities. In a deployment the witness is operated independently of the signer; the mechanism — two independent keys, a cosignature that verifies, an enforced distinctness check — is the same either way.
4 · A transparency-log inclusion proof¶
A signature proves who; a transparency log proves the record wasn't quietly rewritten. The receipt chain head is anchored as a leaf in an append-only RFC-6962 Merkle log, and the bundle carries an offline inclusion proof. Verification is fail-closed and needs no log operator online:
- the leaf re-derives from the receipt's digest;
- the Merkle proof checks against the embedded, signed checkpoint;
- the checkpoint is signed by the pinned log key.
A forged, absent, or wrong-key proof is rejected. A distrusting auditor can prove the gated chain is in an append-only log — not a private rebuild — without trusting recurve to operate one.
The whole thing verifies offline¶
tools/verify_all.py re-runs every check above against the files on disk and the
published public key:
[ok ] verdict verdict-9f9933de0283.json
[ok ] dsse dsse-verdict-9f9933de0283.json
[ok ] witness every verdict independently cosigned
[ok ] include inclusion-9f9933de0283.json
[ok ] release auths-curve-0.1.0.tar.gz
ALL VERIFIED (offline)
No network, no CA, no server — see Verify it yourself to run it against a fresh clone.