|
| 1 | +<!-- SPDX-FileCopyrightText: Sudo Apt Holdings LLC --> |
| 2 | +<!-- SPDX-License-Identifier: Apache-2.0 --> |
| 3 | +# Trinity's receipts and RFC 9943 |
| 4 | + |
| 5 | +RFC 9943, *An Architecture for Trustworthy and Transparent Digital Supply Chains* (IETF SCITT, |
| 6 | +Standards Track, June 2026), standardises the class of object Trinity's receipts belong to. This page |
| 7 | +says exactly where Trinity sits relative to it, including the part that does not fit. |
| 8 | + |
| 9 | +## The terminology, first, because it is a collision |
| 10 | + |
| 11 | +SCITT uses two words that Trinity uses one of. |
| 12 | + |
| 13 | +| SCITT | Issued by | What it asserts | |
| 14 | +|---|---|---| |
| 15 | +| **Signed Statement** | the Issuer | an identifiable, non-repudiable statement about an artifact | |
| 16 | +| **Receipt** | a **Transparency Service** | a cryptographic proof that a Signed Statement is included in a Verifiable Data Structure | |
| 17 | + |
| 18 | +A SCITT Receipt **MUST** carry inclusion proofs. Trinity operates no Transparency Service, maintains |
| 19 | +no Verifiable Data Structure, and issues no inclusion proofs: it keeps a local, single-writer hash |
| 20 | +chain with signed checkpoints. |
| 21 | + |
| 22 | +**So what Trinity calls a receipt is, in SCITT's vocabulary, a Signed Statement.** Nothing Trinity |
| 23 | +emits is a SCITT Receipt, and this project makes no such claim. The name predates the RFC in this |
| 24 | +tree and is not being changed, because "receipt" is the right word for what it is to the person who |
| 25 | +owns the machine; but a reader who knows SCITT should not have to work this out for themselves. |
| 26 | + |
| 27 | +## The envelope Trinity signs with today |
| 28 | + |
| 29 | +The signature is not over the canonical JSON directly. It is over DSSE's pre-authentication encoding |
| 30 | +of a payload type and that JSON, where the payload type is `trinity/receipt/<scheme>` |
| 31 | +(`Trinity.Receipts.Envelope.receipt_type/1`). So the envelope is already a published construct, just |
| 32 | +a different one from SCITT's: DSSE rather than COSE. That matters for the last section. |
| 33 | + |
| 34 | +## The field mapping |
| 35 | + |
| 36 | +Trinity's signed payload is RFC 8785 canonical JSON of exactly these ten keys |
| 37 | +(`Trinity.Receipts.ChainWriter`, the `body` map): |
| 38 | + |
| 39 | +`scheme`, `seq`, `chain_scope`, `prev_hash`, `kind`, `subject`, `decision`, `fingerprint`, `at`, |
| 40 | +`key_id`. |
| 41 | + |
| 42 | +`subject_ref` and `meta` are columns on the row but are **not** in the signed payload, so they are |
| 43 | +not covered by the signature and are not mapped below. |
| 44 | + |
| 45 | +| Trinity | SCITT / COSE / CWT | Note | |
| 46 | +|---|---|---| |
| 47 | +| `scheme` | COSE `alg` (label 1) | Trinity's scheme names the signature and digest algorithms together; COSE separates them. | |
| 48 | +| `key_id` | COSE `kid` (label 4) | Same role: which key, without saying which algorithm. | |
| 49 | +| `at` | CWT `iat` | RFC 3339 here, epoch seconds there. | |
| 50 | +| `kind` | COSE `content_type` (label 3) | Trinity's is a closed vocabulary of five (`Trinity.Receipts.Receipt.kinds/0`: `decision`, `effect`, `query`, `boot`, `cap`); COSE's is a media type. | |
| 51 | +| `subject` | CWT `sub` (claim 2) | SCITT requires a single `tstr`; Trinity's signed `subject` is a map of references. Mapping it needs a canonical string form chosen, which is a decision, not a rename. | |
| 52 | +| *(absent)* | CWT `iss` (claim 1), **required** | Trinity has no issuer field. A single-operator machine has one issuer and it is implied by the key, which is why it was never needed and is exactly what a standards-track reader would look for first. | |
| 53 | +| `decision`, `fingerprint` | the statement payload | Domain content. SCITT does not constrain it. | |
| 54 | +| `seq`, `chain_scope`, `prev_hash` | **no equivalent** | These are the hash chain. In SCITT the equivalent guarantee comes from a Transparency Service's Verifiable Data Structure and is carried in a Receipt's proofs, not in the statement. Trinity's chain is the whole of its tamper-evidence, and it is local. | |
| 55 | + |
| 56 | +## Why the field names are not being renamed |
| 57 | + |
| 58 | +The obvious next step looks like renaming Trinity's fields to their COSE and CWT equivalents so a |
| 59 | +receipt "looks standard". That would be worse than leaving it, for one reason: **the object would |
| 60 | +then read as conformant while not being conformant.** A reader who recognises `iss`, `sub`, `kid` |
| 61 | +and `iat` has been told, by the shape of the thing, that this is a SCITT object, and will reasonably |
| 62 | +expect the rest of SCITT: a Transparency Service, a verifiable data structure, inclusion proofs. |
| 63 | +None of that exists here. |
| 64 | + |
| 65 | +That is a claim made by appearance rather than by a row in `docs/09-standards-register.md`, which is |
| 66 | +the specific failure this project's standards register exists to prevent. |
| 67 | + |
| 68 | +**What would be real, rather than cosmetic**, is emitting the statement as a `COSE_Sign1` object with |
| 69 | +CWT claims `iss` and `sub` in its protected header, in place of the DSSE pre-authentication encoding |
| 70 | +described above. That makes a Trinity statement genuinely readable by a SCITT-aware verifier rather |
| 71 | +than merely familiar-looking. It is a change of signing envelope, with a scheme bump and a |
| 72 | +dual-reading verifier behind it, and it is a decision for the owner rather than a rename anybody can |
| 73 | +do. |
| 74 | + |
| 75 | +## What this page lets a reader conclude |
| 76 | + |
| 77 | +- Trinity's receipts are **Signed Statements** in SCITT's sense, not Receipts. |
| 78 | +- Their integrity comes from a local hash chain with signed checkpoints, not from a transparency log. |
| 79 | +- Every element of the signed payload maps to a published construct, and the three that do not map |
| 80 | + (`seq`, `prev_hash`, `chain_scope`) are the ones SCITT delegates to a service Trinity does not run. |
| 81 | +- `subject_ref` and `meta` are unsigned row columns. Nothing should be inferred from them. |
| 82 | +- No conformance to RFC 9943 is claimed, and none should be inferred. |
0 commit comments