Inference Delivery Receipt — Format Specification (v1)
Status: Published 2026-08-11 · schema 1
Purpose: A vendor-neutral, definitional specification of a content-bound, dual-signed inference delivery receipt for implementers, auditors, and agent tooling.
Non-goals: Marketing copy, pricing, marketplace listing text, SDK packaging.
1. Abstract
An inference delivery receipt is a small, offline-verifiable cryptographic object that attests:
At time T, under environment E, for tenant N, an issuer with key id K asserts that
a specific input (by hash), output (by hash), model weights (by digest), and
runtime measurement (e.g. enclave PCR) participated in one inference event,
identified by receipt_id.
It is not:
- Proof of training-data provenance or dataset copyright
- Proof that a human authorized a payment (that is payment-mandate / agent-identity territory)
- A substitute for an independent third-party auditor unless the verifier independently holds the hashed material and trusts the key distribution
Payment binding (optional) lives outside this format — e.g. in an HTTP 402 / x402 extension envelope that references receipt_id and may add settlement identifiers and HTTP entity digests. See §7.
1.1 Sibling products (non-confusion) — MUST
This document defines only the inference delivery receipt.
Other dual-signed receipt products — including attestation / policy-verify receipts returned by document-verify APIs — use a different domain-separation context and different body fields (e.g. verdict, doc_sha256, measurements). Those products:
- MAY share the same envelope/crypto stack (Ed25519 + ML-DSA-44,
kid, offline verify), and - do not conform to §4, and
- MUST NOT be described as inference delivery receipts under this specification.
Implementers MUST NOT treat every dual-signed wire blob as §4-conformant.
§4 fields (enclave_measurement, input_hash, output_hash, weights_digest, …) apply only where an issuer mints an inference delivery body.
2. Conformance classes
| Class | Requirement |
|---|---|
| full | Dual signatures: classical Ed25519 + post-quantum ML-DSA-44 (FIPS 204) over the same canonical body under a fixed domain-separation context string |
| classical-only | Ed25519 only — allowed for constrained verifiers; MUST be labeled; MUST NOT claim PQ assurance |
A verifier that requires full MUST reject classical-only envelopes.
3. Identifiers and domain separation
| Item | Rule |
|---|---|
| Field names | Wire-literal snake_case in the signed body. No silent camelCase rename on the crypto boundary. |
receipt_id |
Issuer-assigned, non-empty string. Opaque. Stable for the lifetime of the receipt. |
| Domain context | Signatures MUST use an explicit context string (domain separation) so a signature under one product surface cannot be replayed under another. |
| Example context (informative) | vendor.tld/attestation/inference-receipt/v1 (informative reverse-DNS example) — implementations MUST use a fixed context string per schema version. |
| Schema version | Integer schema field in the body. This document defines schema = 1. |
4. Signed body (schema 1)
All multi-byte cryptographic fields below are raw 32-byte digests unless noted; on the wire they MAY be hex- or base64url-encoded so long as the canonical preimage for signing is defined and fixed (see §5).
| Field | Type | Required | Meaning |
|---|---|---|---|
schema |
uint | yes | Must be 1 for this specification |
alg |
uint | yes | 1 = dual-sign Ed25519 + ML-DSA-44 |
env |
string | yes | Logical environment label, e.g. live or sandbox |
ts |
uint | yes | Unix time in seconds (UTC) of issuance. Not renamed to iat — that wire name belongs to the attestation/verify sibling body; this format freezes ts (schema 1). |
nonce |
bytes(32) | yes | Fresh uniqueness salt |
tenant |
string | yes | Opaque tenant id (not a mutable display name) |
receipt_id |
string | yes | Issuer receipt id |
input_hash |
bytes(32) | yes | SHA-256 of the input material as bound by the issuer |
output_hash |
bytes(32) | yes | SHA-256 of the output material as bound by the issuer |
weights_digest |
bytes(32) | yes | SHA-256 of the weights artifact W (preimage below) |
enclave_measurement |
bytes(32) | yes | Primary runtime measurement (e.g. Nitro PCR0 of the EIF) |
4.1 Weights preimage (normative)
weights_digest = SHA-256(W)
- If a single file or single contiguous blob is loaded: W is those exact bytes.
- If multiple files: for each relative path in lexicographic UTF-8 order, append
uint64_be(len(path_utf8)) || path_utf8 || uint64_be(len(content)) || content. - W MUST NOT include archive headers, compression wrappers, timestamps, or host metadata.
4.2 Input / output preimages
Issuers MUST document how input_hash and output_hash are formed for their product.
When the delivery channel is HTTP, a separate payment-layer digest MAY bind the decoded HTTP entity body (after Content-Encoding removal); that digest is not a field of this body unless the product defines output_hash to be exactly that preimage.
5. Envelope and signatures
5.1 Logical envelope
An issued receipt is an envelope containing:
- The canonical body (encoding fixed per implementation; CBOR or JSON with a frozen canonicalization rule — both MUST be versioned and test-vectored)
- Key id
kid(32 bytes recommended) identifying the verifying public keys - Ed25519 signature (64 bytes)
- ML-DSA-44 signature (2420 bytes) for class full
Informative arity: five-element envelope (version, body, kid, ed25519_sig, ml_dsa_sig) has been used in production implementations; the normative requirement is dual-sig full class completeness, not a specific CBOR tag layout.
5.2 Verification (full class)
- Parse envelope; reject malformed arity / lengths.
- Resolve
kidagainst a caller-supplied keyset (or a pinned HTTPS keyset URL the verifier trusts). - Recompute the body preimage under the fixed domain context.
- Verify Ed25519 and ML-DSA-44; both MUST succeed for full.
- Check
schema/algsupported. - Apply verifier policy on
ts,env, and key status (active / retired / revoked).
Offline-by-default: verification MUST NOT require a network call when the keyset and receipt bytes are already local. Network is only for optional key fetch or optional public-ledger inclusion (§7).
5.3 Exit / result codes (CLI-oriented, informative)
| Code | Meaning |
|---|---|
| 0 | Valid (and inclusion valid if requested) |
| 1 | Usage / IO / incomplete inputs |
| 2 | Invalid receipt or inclusion |
6. What the receipt does not claim
Normative non-claims (product language MUST respect these):
- Not training provenance. No statement about datasets, copyright, or training runs.
- Not payment authority. Does not prove a human or agent was authorized to spend.
- Not global delivery proof alone. A hash without the corresponding bytes held by the verifier is not delivery proof to that verifier.
- Not a substitute for key trust. Verifiers must obtain authentic public keys out of band or via a pinned key distribution channel.
7. Optional: public day inclusion
A receipt MAY be included in a daily Merkle ledger under:
| Binding | Value |
|---|---|
| Leaf identity | request_id = receipt_id |
| Endpoint label | product-defined constant (informative example: pcrzero.pom.infer.v1) |
| Units | typically 1 per receipt |
Inclusion proofs (event path + tenant path + checkpoint package + anchors) are orthogonal to dual-sign verify. A verifier MAY:
- Verify the receipt offline (§5), then
- Verify inclusion against a caller-supplied checkpoint and anchors (zero phone-home if all files local).
8. Optional: payment binding (x402 and similar)
Payment protocols (e.g. x402) MAY attach a receipt by reference, not by rewriting §4:
| Layer | Role |
|---|---|
| This format (§4–§5) | Content-bound dual-sign body |
| Payment extension envelope | Settlement id (transaction xor commitmentId xor explicit unbound), optional HTTP decoded-entity contentHash, pointer receipt_id / fetch URL |
Rules of composition:
- Frozen body fields MUST NOT be redefined by the payment envelope.
- If both a payment-layer
contentHashandoutput_hashexist, the product MUST document whether they share a preimage. - Batch settlement schemes MUST use a commitment identifier, not a fake transaction hash.
A separate draft extension key (a product-specific extension key) and an upstream offer-receipt v2 delta are product / standards tracks, not required to implement this format.
9. Test vectors
A conforming implementation MUST ship:
- At least one valid dual-sign vector (golden body + signatures + keys)
- At least one invalid signature vector
- Boundary tests for weights multi-file preimage ordering
Vector format SHOULD be language-neutral JSON (hex fields) so independent implementations can assert the same intermediates.
Reference vectors (this repository): inference-receipt-vectors-v1.json
(schema freeze companion; dual-sign golden + invalid cases).
10. Versioning
| Change type | Action |
|---|---|
| New optional field, ignore-unknown safe | New minor doc revision; schema stays 1 only if signing preimage unchanged |
| Signing preimage or required field change | New schema integer + new domain context string |
| Alg suite change | New alg code + conformance class update |
11. Security considerations (summary)
| Threat | Mitigation in this format |
|---|---|
| Cross-product signature replay | Domain context string |
| Key confusion | Explicit kid + keyset status |
| PQ-only or classical-only downgrade | Conformance class labels |
| Settlement / payment confusion | Payment binding outside body (§8) |
| Header size for dual-sig | Prefer fetch-by-reference for large envelopes |
Full threat models for payment binding and gateway emission live in separate design documents.
12. References (informative)
- FIPS 204 (ML-DSA)
- Ed25519
- x402 specifications (payment extensions; settlement schemes including batch-settlement)