Conformance Test Suite

Pass all six mandatory suites to earn the SignedReceipt v1 compatible badge. The suite is open-source under Apache-2.0 at github.com/signedreceipt/conformance .

Run the suite

cargo install signedreceipt
git clone https://github.com/signedreceipt/conformance
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. Submit a pull request to github.com/signedreceipt/conformance with your implementation output in implementations/<your-impl-name>/result.json.
  4. The PR is reviewed by the SignedReceipt maintainers. On merge, your implementation is listed at signedreceipt.org/implementations.

Submission

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

# Fork and submit
git clone https://github.com/signedreceipt/conformance
cd conformance
mkdir -p implementations/your-impl-name
cp /path/to/result.json implementations/your-impl-name/result.json
cp /path/to/implementation-info.json implementations/your-impl-name/info.json
git checkout -b add-your-impl
git add implementations/
git commit -m "Add conformance results for your-impl-name v1.0"
git push origin add-your-impl
# Open a PR at github.com/signedreceipt/conformance

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 100% of mandatory suites:

Read the specification View on GitHub