transparency: an external encoding, and a witness for the receipt chain #89

Merged
dcharlot merged 1 commit from wai/transparency-emission into main 2026-09-10 12:23:16 -04:00

View file

@ -0,0 +1,111 @@
# WAI Extension: Transparency Emission
> Status: Draft. Adds an **external encoding** for WAI receipts so a party with
> no WAI tooling can check them, and a registration profile so a receipt's
> existence is independently witnessed. Strictly **additive**: the JWP receipt
> chain is unchanged, and nothing here replaces it.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
## 1. What is actually missing
Not verifiability. An Ed25519 signature over a group Merkle root is checkable by
anyone holding the publisher key, and [`jwp-receipts`](jwp-receipts.md) §3
specifies exactly how. Three properties are missing, and none of them is a
signature property:
- **Non-equivocation.** Nothing prevents a publisher showing one receipt chain to
one party and a different chain to another. Both verify.
- **Independent timestamping.** A receipt says when the publisher says it was
made.
- **Detectability of suppression.** A receipt that was never shown to anyone
leaves no trace of its absence.
These are log properties, not envelope properties, and they are why this
extension exists.
## 2. The move, and its shape
The family already owns both halves: a transparency log with consistency proofs
exists, and JCR-1 (deterministic CBOR + COSE_Sign1, RFC 9052) is already the
canonical receipt envelope across sibling standards. What nothing in the family
has is a **standardised external encoding** that an outside auditor's
off-the-shelf tooling can verify with no bespoke verifier.
So the sequence is: bring WAI's receipts onto JCR-1 as its siblings already are,
then emit in the standardised encodings on top.
- A WAI receipt **SHOULD** be expressible as a JCR-1 envelope. This is alignment
with the family, not a new format.
- An implementation **MAY** additionally emit an RFC 9942 (COSE Receipts)
encoding of a group receipt, and **MAY** use the RFC 9995 COSE Hash Envelope
form where the payload is carried by hash rather than by value.
- These emissions are **additional encodings of the same facts**. An implementation
**MUST NOT** let the JWP chain and an emitted encoding disagree, and where they
do, the JWP chain is authoritative and the emission is in error.
## 3. What is registered, and what is not
SCITT registers per-artifact Signed Statements over an HTTP API. WAI emits
per-object receipts at media-group cadence. These cadences do not match, and
forcing them together would put a registration round-trip in the per-object path.
- An implementation **MUST NOT** register per-object receipts individually.
- An implementation **SHOULD** register the **group** receipt, or periodic
checkpoints over the receipt chain, leaving the per-object receipt exactly
where it is.
- Registration **MUST NOT** be a precondition for a receipt being valid. An
unregistered receipt is a receipt whose existence is unwitnessed, not a receipt
that is wrong.
The checking party is the **Relying Party** in the terminology of the SCITT
architecture; this extension uses that term rather than coining another.
## 4. The hash-algorithm constraint
RFC 9995's `payload_hash_alg` takes an identifier from the COSE Algorithms
registry. **BLAKE3 — which `jwp-receipts` §2.1 uses throughout — does not appear
in that registry.**
This is a real constraint, not a detail to be waved through:
- An implementation **MUST NOT** emit a COSE Hash Envelope naming BLAKE3 by an
unregistered or invented identifier. An identifier a Relying Party cannot
resolve defeats the entire purpose of emitting in a standard encoding.
- Until a registration exists, an implementation **MUST** either omit the hash
envelope form, or carry a **second digest** under a registered algorithm
alongside the BLAKE3 commitment, stating plainly that the two cover the same
bytes.
- A dual-hash carry **MUST NOT** be presented as evidence that BLAKE3 is
registered.
Registering BLAKE3 in the COSE Algorithms registry is a separate action with its
own process, and this extension does not assume its outcome.
## 5. Stage discipline
The referenced work is at mixed maturity, and an implementation **MUST NOT**
present any of it as more settled than it is:
| document | status |
|---|---|
| SCITT architecture (RFC 9943) | Standards Track, published |
| COSE Receipts (RFC 9942) | Standards Track, published |
| COSE Hash Envelope (RFC 9995) | published |
| SCRAPI (registration/resolution API) | approved, in the RFC Editor queue |
| a concrete log profile | Working Group Last Call — **not ratified** |
An implementation **MUST NOT** describe the log profile as ratified, and
**SHOULD** state which profile it registered against, since a Relying Party
cannot check a proof without knowing the log's rules.
## 6. What this does not do
- It does **not** replace the JWP receipt chain, and it does **not** move the
per-object commitment anywhere.
- It does **not** make registration a trust anchor. A Transparency Service
witnesses that a receipt existed at a time; it does not attest that the receipt
is true, and an implementation **MUST NOT** report registration as
verification.
- It does **not** solve key discovery. That is [`jwp-receipts`](jwp-receipts.md)
§7, and a log entry naming a key the Relying Party cannot resolve is still
unresolvable.