Minimum Integration, 3 Steps
- Build CER bundle, Render via CLI or API, receive a sealed CER bundle JSON with hashes.
- Attest to node, Submit the CER bundle JSON to a canonical attestation node for a signed receipt.
- Store bundle + proof, Persist the CER bundle JSON and signed receipt for audit.
Step 1, Build CER Bundle
Render your code through the CLI. The output includes a CER bundle JSON file (out.snapshot.json) that binds your code, seed, VARs, and rendered output together with SHA-256 hashes.
# Render and generate CER bundle JSON
npx --yes @nexart/cli@1.2.0 run ./examples/sketch.js \
--seed 12345 \
--vars "50,50,50,0,0,0,0,0,0,0" \
--include-code \
--out out.png
# Verify CER bundle integrity locally
npx --yes @nexart/cli@1.2.0 verify out.snapshot.json
# Output: [nexart] Result: PASSThe CER bundle JSON (out.snapshot.json) contains the certificateHash, a SHA-256 digest over the canonical JSON of the bundle's core fields. Any modification to the code, seed, parameters, or output invalidates this hash.
Step 2, Attest to Node
Submit the sealed CER bundle JSON to a canonical attestation node. The node verifies internal hash consistency and returns a signed receipt proving the bundle was recorded in the proof ledger.
# Attest the CER bundle JSON to the canonical node
npx --yes @nexart/cli@1.2.0 attest out.snapshot.json \
--nodeUrl https://nexart-canonical-renderer-production.up.railway.app \
--apiKey $NEXART_API_KEYExpected output fields:
{
"attestationId": "att-abc123...",
"signature": "<Ed25519 signature, base64url>",
"kid": "<attestorKeyId from node's .well-known/nexart-node.json>"
}Important: Attestation verifies the bundle's hashes and returns a signed receipt. It does not re-run your code, re-render the output, or alter the recorded CER bundle in any way.
Step 3, Store Bundle + Proof
Persist the full CER bundle JSON along with the signed receipt. This gives you a complete audit trail: the sealed execution record plus third-party proof of integrity.
// The CER bundle JSON contains everything needed for offline verification:
// - snapshot (codeHash, seed, VARs, renderHash, protocolVersion)
// - certificateHash (integrity seal)
// - receipt + signature + attestorKeyId (node attestation proof)
// Store to your database or archive
await db.insert('cer_bundles', {
certificate_hash: bundle.certificateHash,
cer_bundle_redacted: redact(bundle),
attestation_json: proof,
});What Gets Stored vs. What Can Be Redacted
| Field | Stored | Redactable | Notes |
|---|---|---|---|
certificateHash | Always | No | Required for verification |
snapshot.codeHash | Always | No | Binds code to output |
snapshot.renderHash | Always | No | Binds rendered PNG |
snapshot.seed | Always | No | Required for deterministic replay |
snapshot.vars | Always | No | Input parameters (VAR[0..9]) |
snapshot.protocolVersion | Always | No | Protocol version used for render |
snapshot.code | Optional | Yes | Source code (may be proprietary) |
meta | Optional | Yes | Excluded from certificate hash |
receipt | Recommended | No | Node attestation proof |
signature | Recommended | No | Ed25519 signature over receipt |
attestorKeyId | Recommended | No | Key ID for signature verification |
nodeRuntimeHash | Optional | Yes | Legacy attestation field |
Redaction rule: Delete keys or set them to null. Never set to undefined, it is not valid JSON and will break canonical serialization.
Reason Codes
When you or an auditor verifies a Code Mode CER bundle, the result includes a machine-readable reason code:
| Code | Meaning |
|---|---|
OK | All hashes match. Record is intact. |
CERTIFICATE_HASH_MISMATCH | The bundle's seal doesn't match its contents, something was modified. |
SNAPSHOT_HASH_MISMATCH | Both input and output hashes are wrong, likely a reconstructed bundle. |
RENDER_HASH_MISMATCH | The rendered output doesn't match the recorded hash. |
CODE_HASH_MISMATCH | The source code doesn't match its recorded hash. |
INVALID_SHA256_FORMAT | A hash field is malformed (doesn't start with sha256:). |
SCHEMA_ERROR | Missing required fields or wrong bundle type. |
NODE_RECEIPT_MISSING | No signed receipt found, stamp incomplete. |
NODE_RECEIPT_INVALID_SIGNATURE | The Ed25519 signature on the receipt didn't verify. |
Try It
End-to-end demo: Render a sketch via the CLI, then verify the output independently.
- Run:
npx --yes @nexart/cli@1.2.0 run ./examples/sketch.js \ --seed 42 --include-code --out demo.png - Open
demo.snapshot.json, inspect thecertificateHash - Verify on Recânon: upload the CER bundle JSON to audit integrity