sha256 pins on the official GS1 schemas: what PINS.json buys you.
31 July 2026 · the launch journal
Every EPCIS vendor's security questionnaire answer contains the sentence "we validate against the official schema." Before you accept it, ask the only question that matters: which bytes? A schema fetched from a CDN at build time is whatever the CDN served that day — subject to silent revisions, mirror drift, a compromised edge, or a well-meaning maintainer "fixing" a regex. If the validator's authority can change without anyone deciding it should, then "validated" is a timestamp, not a property. Provenance of the validator is as load-bearing as the validation result.
So this project treats the official artefacts the way you treat dependencies you actually trust: vendored, pinned by digest, and changed only by journaled human ruling. The pin file is public. Here is vendor/gs1/PINS.json, abridged only for width:
{
"description": "Pinned GS1 EPCIS 2.0.1 normative artefacts, vendored per
spec 02 §2.1. Source of the standard: GS1 (ref.gs1.org). Pins change
only by journaled human ruling.",
"standard": "EPCIS 2.0.1",
"artefacts": {
"epcis-json-schema.json": {
"url": "https://ref.gs1.org/standards/epcis/epcis-json-schema.json",
"sha256": "0f46ff694efffd8d8ce840a33dfde84228add11b516b8b258f3200740ae210af",
"retrievedAt": "2026-07-19",
"role": "document/event validation — the projection-invariant schema"
},
"epcis-context.jsonld": {
"url": "https://ref.gs1.org/standards/epcis/epcis-context.jsonld",
"sha256": "5056c65f991425b1d3a35e35edf4f7d0c7ff56cf688c2912b930f93494713737",
"retrievedAt": "2026-07-19",
"role": "JSON-LD expansion checks"
}
}
}
Five artefacts are pinned the same way — the JSON schema, the JSON-LD context, the OpenAPI description (the REST binding for capture and query), the SimpleEventQuery schema, and the SHACL shapes. Each pin is four facts: digest, source URL, retrieval date, role. npx epcis.dev pins prints the record verbatim from wherever you are:
$ npx epcis.dev pins
standard EPCIS 2.0.1
pin epcis-json-schema.json sha256=0f46ff694efffd8d8ce840a33dfde84228add11b516b8b258f3200740ae210af https://ref.gs1.org/standards/epcis/epcis-json-schema.json
pin epcis-context.jsonld sha256=5056c65f991425b1d3a35e35edf4f7d0c7ff56cf688c2912b930f93494713737 https://ref.gs1.org/standards/epcis/epcis-context.jsonld
...
And every validation verdict carries its schema's identity inline — {"schema": {"artefact": "epcis-json-schema.json", "version": "2.0.1", "sha256": "0f46ff69…"}} — so a stored validation result names the exact bytes that judged it.
The gate that makes the pin real.
A pin file that nothing enforces is documentation. The enforcement is verify:pins, a CI gate that re-hashes every vendored artefact against its recorded digest on every run. Here is the demonstration your questionnaire actually wants — one byte appended to the vendored schema, then the gate:
$ printf ' ' >> vendor/gs1/epcis-json-schema.json
$ pnpm verify:pins
❯ test/pins.test.ts (14 tests | 2 failed)
× epcis-json-schema.json: vendored bytes hash to the recorded digest
→ expected '1ba560e8e7de62a4cf8dd81dfd4c729255f22…'
to be '0f46ff694efffd8d8ce840a33dfde84228add…'
× verifyAllPins passes over the whole vendor dir
→ pin digest mismatch: epcis-json-schema.json
A single invisible whitespace byte, and the build refuses. That refusal is the entire security property: no artefact the validator trusts can drift — by accident, by upstream revision, or by tamper — without a red build naming the file and both digests. Restore the byte, fourteen green.
Changing a pin is a ceremony, on purpose.
Pins do change — GS1 publishes revisions, and 2.0.1 itself supersedes 2.0.0. What never happens is a silent change. The rule, stated in the pin file itself: pins change only by journaled human ruling. A version bump is a recorded decision — who ruled, when, old digest, new digest, why — followed by re-vendoring and a full run of the golden corpus against the new bytes. The spec version is pinned too (EPCIS 2.0.1, stamped in the GS1-EPCIS-Version header on every conformant-surface response), so "which standard are you on" has a one-line, machine-readable answer rather than a roadmap slide. The same discipline extends past validation: the CBV §8.9 hash implementation is gated against OpenEPCIS's published reference vectors, themselves vendored and pinned, and the conformance harness pins its own spec texts by digest so the test suite cannot be quietly reshaped around a failing implementation.
Check our pins without asking us.
The point of publishing digests is that you can grade the claim independently, in about two minutes, with no account and no contact with anyone here:
- Fetch the artefacts from the source of the standard: curl -sO https://ref.gs1.org/standards/epcis/epcis-json-schema.json
- Hash them: shasum -a 256 epcis-json-schema.json
- Compare against the conformance page — the same table npx epcis.dev pins prints, published with retrieval dates.
If a digest ever disagrees, one of three things is true: GS1 revised the artefact after our retrieval date, your fetch was tampered with, or ours was. All three are exactly the findings a security review exists to surface — and none of them is discoverable at all under "we validate against the official schema," full stop, no digest.
Pinned, or it didn't validate. Put the line in your questionnaire and send it to every vendor on the shortlist; run npx epcis.dev pins and the validator to see what a complete answer looks like before you do.
We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.