Skip to content

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.