Conformance Test Suite

Pass all six mandatory suites to earn the SignedReceipt v1 compatible badge. The harness is Apache-2.0 and the vectors are CC0. The corpus is documented at signedreceipts.org/source/conformance; a downloadable distribution is being prepared and is not yet published. The fixture counts on this page describe the corpus as it stands in the maintainer’s tree and cannot be independently verified until that distribution is published; the total vector count quoted on /source/conformance (248 known-good + 187 known-bad) counts the full corpus, not the six mandatory suites counted here.

Run the suite

There is no public download or package release yet, so the command below describes the intended workflow once the distribution is published. Request the current corpus from open-source@cloakapi.io in the meantime.

# Planned workflow — nothing is published on crates.io or npm yet
signedreceipt conformance ./conformance/fixtures/ --json

Expected output when all tests pass:

Suite: canonicalisation  PASS 12/12
Suite: signature         PASS 18/18
Suite: chain-linking     PASS 20/20
Suite: claim-schema      PASS 15/15
Suite: key-discovery     PASS 10/10
Suite: version-compat    PASS  8/8

Total: PASS 83/83 (6 suites)

Suite 1 — canonicalisation

Every implementation MUST produce byte-identical output from the same abstract receipt using RFC 8785 JCS. The suite checks twelve fixtures:

FixtureTypeWhat it tests
canon-01.jsonKnown-goodMinimal valid receipt; canonical form matches reference bytes
canon-02.jsonKnown-goodAll optional fields present; canonical form matches reference bytes
canon-03.jsonKnown-goodUnicode in sub field; canonical form encodes as UTF-8 with no BOM
canon-bad-01.jsonKnown-badDuplicate key in JSON object — MUST reject
canon-bad-02.jsonKnown-badBOM at start of file — MUST reject
canon-bad-03.jsonKnown-badNon-LF newlines in string value — MUST reject
canon-bad-04.jsonKnown-badTrailing comma — MUST reject

Suite 2 — signature

Signature verification using ECDSA P-256 SHA-256. DER-encoded signatures are explicitly rejected; only the 64-byte compact form is valid. Eighteen fixtures:

FixtureTypeWhat it tests
sig-01.jsonKnown-goodValid P-256 signature, compact 64-byte form
sig-02.jsonKnown-goodSignature from a rotated (retired) key with valid nbf/exp window
sig-03.jsonKnown-goodSignature from desktop device key (iss contains /keys/desktop/)
sig-bad-01.jsonKnown-badSingle bit flipped in sig field — MUST reject
sig-bad-02.jsonKnown-badDER-encoded signature — MUST reject
sig-bad-03.jsonKnown-badWrong key used (key A signing, key B declared in kid) — MUST reject
sig-bad-04.jsonKnown-badSignature over non-canonical form — MUST reject
sig-bad-05.jsonKnown-badsig field included in signed payload — MUST reject
sig-bad-06.jsonKnown-badKey expired (exp in the past) — MUST reject
sig-bad-07.jsonKnown-badKey not yet valid (nbf in the future) — MUST reject

Suite 3 — chain-linking

Receipt chains are valid iff every receipt's prev_hash matches the SHA-256 of its predecessor's canonical bytes including the sig field, and seq increments by exactly 1 with no gaps. Twenty fixtures:

FixtureTypeWhat it tests
chain-good-01/Known-goodThree-receipt chain: seq 0, 1, 2; all links valid
chain-good-02/Known-goodSingle receipt with prev_hash null (first in session)
chain-good-03/Known-goodCross-chain link: child chain referencing parent jti
chain-bad-01/Known-badSeq gap: 0, 1, 3 (missing 2) — MUST reject
chain-bad-02/Known-badFork: two receipts both claim seq=1 — MUST reject
chain-bad-03/Known-badWrong prev_hash (single byte changed) — MUST reject
chain-bad-04/Known-badNon-null prev_hash on seq=0 receipt — MUST reject
chain-bad-05/Known-badseq decrement (1, 0) — MUST reject

Suite 4 — claim-schema

Required fields must be present and valid. No plaintext PII may appear in any signed field. Fifteen fixtures:

FixtureTypeWhat it tests
schema-good-01.jsonKnown-goodMinimal valid claims object
schema-good-02.jsonKnown-goodAll claim types present: tokenisation, routing, egress, countersignature
schema-good-03.jsonKnown-goodVendor extension claims under x-vendor-* namespace — MUST pass through
schema-bad-01.jsonKnown-badMissing required v field — MUST reject
schema-bad-02.jsonKnown-badEmail address in sub field — MUST reject (PII check)
schema-bad-03.jsonKnown-badPhone number in claims.tokenisation detector fingerprint — MUST reject
schema-bad-04.jsonKnown-badCredit card pattern in routing_decision.reason — MUST reject
schema-bad-05.jsonKnown-badNon-ULID jti — MUST reject
schema-bad-06.jsonKnown-badUnknown tokenisation level enum value — MUST reject

Suite 5 — key-discovery

Implementations MUST resolve kid via the issuer's /.well-known/cloakapi-receipt-pubkeys.jwks or an equivalent endpoint. Unknown kids MUST be rejected. Ten fixtures:

FixtureTypeWhat it tests
key-good-01Known-goodCurrent kid resolves to active key
key-good-02Known-goodRetired kid resolves to retired key within its validity window
key-bad-01Known-badUnknown kid — MUST reject
key-bad-02Known-badRetired kid outside validity window (past exp) — MUST reject
key-bad-03Known-badJWKS endpoint unreachable and no cached key — MUST reject (not silently pass)

Suite 6 — version-compatibility

v1 envelope required fields must be present. Unknown x-* vendor claims MUST be ignored (not rejected). Future versions of the spec MUST NOT cause v1 verifiers to crash. Eight fixtures:

FixtureTypeWhat it tests
compat-good-01.jsonKnown-goodv1 receipt with x-acme-audit vendor extension — MUST verify OK
compat-good-02.jsonKnown-goodv1 receipt with unknown top-level field (forward-compat) — MUST verify OK
compat-bad-01.jsonKnown-badv field set to v0 (no such version) — MUST reject
compat-bad-02.jsonKnown-badv field set to v2 (future, not yet implemented) — MUST reject with version-unknown error

Badge criteria

To display the "SignedReceipt v1 compatible" badge, your implementation must:

  1. Pass 100% of all six mandatory suites (83/83 fixtures).
  2. Run the suite against a publicly hosted endpoint or a local test server.
  3. Send your implementation output (result.json) and info.json to open-source@cloakapi.io. There is no public pull-request workflow yet — the repository has not been published.
  4. The submission is reviewed by the maintainer. On acceptance, your implementation is listed at signedreceipts.org/implementations.

Submission

# Run the suite and save results
signedreceipt conformance ./conformance/fixtures/ --json > result.json

# Then email result.json + info.json to open-source@cloakapi.io
# (no public repository or PR workflow exists yet)

The info.json file should contain:

{
  "name": "your-impl-name",
  "version": "1.0.0",
  "language": "typescript",
  "repo": "https://github.com/your-org/your-impl",
  "contact": "your@email.com"
}

Reference implementations

Both reference implementations pass every mandatory suite in the maintainer's own runs. Because the corpus is not published yet, that result is not independently reproducible today:

Read the specification Browse the conformance corpus