Canonicalization
How Vitrified turns a submission into a deterministic byte sequence so leaf identifiers reproduce exactly across clients and runtimes.
Canonicalization
A submission's leaf identifier must reproduce exactly across SDKs, runtimes, and re-submissions — otherwise verifiers can't reconstruct the leaf from the original inputs. Vitrified pins canonicalization to JCS (JSON Canonicalization Scheme, RFC 8785) so any conformant JSON canonicalizer produces the same bytes.
The rule
leaf_sha256 = SHA-256(JCS(submission_envelope))
Where submission_envelope is a JSON object containing the artifact hash, the declared metadata
schema, and the metadata payload. The exact field order in your source code doesn't matter; JCS
sorts keys lexicographically, normalizes number encoding, and uses a single, deterministic UTF-8
serialization.
What JCS guarantees
- Key ordering. Object keys are sorted lexicographically by their Unicode code-point sequence.
- Number normalization. Numbers serialize to the shortest IEEE-754 form.
1.0,1, and1e0all canonicalize to1. - String normalization. Strings serialize as UTF-8 with the minimum set of escapes required by JSON. No optional whitespace.
- No insignificant whitespace. No spaces between tokens.
- No ambiguity. For any JSON value, the canonical byte sequence is unique.
Reference implementations
The canonicalization implementations live in this repository and ship in every SDK:
- Python:
services/api/src/vitrified_service/canonicalization/ - JavaScript / TypeScript: bundled in
@vitrified/sdkvia thecanonicalize()export.
Both implementations are tested against the shared test vectors at
spec/canonicalization/test-vectors/
on every commit, so cross-language drift is a CI failure.
What Vitrified does not canonicalize
Vitrified never canonicalizes the bytes of your artifact. The canonicalization rule applies only to the submission envelope — the JSON wrapper containing the hash and metadata. Your artifact bytes are exactly what you hashed; nothing on the wire transforms them.
Canonicalization helpers for artifact-side normalization (CRLF vs. LF, BOM stripping, JSON re-serialization of your own JSON artifacts) exist in the SDK as explicit function calls you choose to invoke. They are never applied silently.
See also
- Proof bundle — how the leaf identifier appears in the bundle.
- Spec: canonicalization — the normative rule and the cross-language test vectors.
Proof bundle
The on-the-wire shape of a Vitrified proof bundle and what each field means for verification.
Submission policy
Metadata validation, foot-gun warnings, rate limits, idempotency, and retention.
Was this page helpful?