Locked v1 schema hash: sha256:103e0121f3f5b71b9a6a8489feb7159c0e99518f1bb0f5fbee6e1709ec16f40f
Korzent defines a deterministic, cryptographically verifiable execution governance standard. It binds intent, policy, and outcome into signed receipts that can be verified offline without coordination services. The protocol is intentionally minimal: canonical JSON, schema-hash anchoring, Ed25519 signatures, and strict fail-closed verification. Korzent does not define runtimes, orchestration, or coordination—only the invariant receipt layer that proves authority-before-execution and auditability after the fact.
- Deterministic: identical verification outcomes across platforms and implementations
- Minimal surface area: only what is required to prove authority and auditability
- Cryptographic clarity: canonical JSON, Ed25519, SHA-256 with explicit encoding rules
- Fail-closed: any deviation results in rejection; no compatibility modes
- Offline verifiable: receipts can be verified without network calls or coordination services
Korzent specifies:
- Receipt structure and canonicalization rules
- Schema-hash anchoring and protocol identity
- Ed25519 signing and receipt_id derivation
- Three receipt kinds: Evaluation, Execution, Attempt
- Strict verification invariants
Out of scope:
- Runtime authorization enforcement
- Operator authentication systems
- Policy distribution or key registry services
- Orchestration engines or workflow semantics
- SaaS configuration or marketplace features
These belong in higher-layer implementations.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
- All signed and hashed JSON values MUST be canonicalized with RFC8785 (JSON Canonicalization Scheme).
- Canonicalization output MUST be byte-stable across platforms and runtimes.
- Implementations MUST treat canonicalization as a deterministic, pure function with no runtime-dependent formatting behavior.
- Hash algorithm: SHA-256.
- Hash reference encoding:
sha256:<lower-hex>where<lower-hex>is exactly 64 lowercase hexadecimal characters.
schema_hash = "sha256:" + SHA256(RFC8785(canonical JSON of receipt.schema.json)).hexLowerschema_hashMUST equalKORZENT_V1_SCHEMA_HASHexactly.
protocolfield MUST be"korzent".protocol_versionfield MUST be"1.0.0".protocol_id = "korzent:1.0.0:" + KORZENT_V1_SCHEMA_HASH.
- Let
unsigned_receipt_json_for_idbe the receipt object with bothsignatureandreceipt_idomitted. receipt_id = "sha256:" + SHA256(RFC8785(unsigned_receipt_json_for_id)).hexLower
- Signature encoding is locked to base64url (no padding) and MUST be exactly 86 characters.
- Let
unsigned_receipt_json_for_sigbe the receipt object withsignatureomitted (and with derivedreceipt_idpresent). signature = Ed25519Sign(privateKey, SHA256(RFC8785(unsigned_receipt_json_for_sig)))- The exact bytes signed are the 32-byte SHA-256 digest of canonicalized unsigned receipt JSON.
- EvaluationReceipt: policy evaluation output (
decisionisALLOWorDENY). - ExecutionReceipt: execution output for
ALLOWonly; MUST includeparent_receipt_idlinking to its decision receipt. - AttemptReceipt: boundary pre-evaluate failure receipt (
decisionisDENYonly) to satisfy always-receipt behavior.
intent_hash = "sha256:" + SHA256(RFC8785(intent_json)).hexLowerintent_hashMUST NOT beZERO_HASH`.
ZERO_HASH = "sha256:" + 64 * "0".ZERO_HASHis allowed only for AttemptReceiptpolicy_pack_hashandepoch_hashwhen those values are unavailable.ZERO_HASHis forbidden for:intent_hashin all receipt kindspolicy_pack_hashandepoch_hashin EvaluationReceipt and ExecutionReceipt.
- AttemptReceipt intent hashing uses a deterministic portable payload:
{
"kind": "ATTEMPT",
"route": "/v1/actions/governed",
"deny_code": "<deny_code>",
"inputs_snapshot_hash": "<hashRef>",
"driver": "<driver_name_or_empty_string>"
}- AttemptReceipt
intent_hashMUST be the RFC8785 SHA-256 hash-ref of this object.
- Reject if
protocol != "korzent". - Reject if
protocol_version != "1.0.0". - Reject if
schema_hashis missing. - Reject if
schema_hash != KORZENT_V1_SCHEMA_HASH. - Reject if
trust_root_idis missing. - Reject if
signing_key_idis missing. - Reject if
signatureis missing or invalid. - Reject if signature length is not exactly 86.
- Reject if any required schema field is missing.
- Reject if execution receipt has
decision != "ALLOW". - Reject if attempt receipt has
decision != "DENY". - Reject if attempt receipt
deny_codeis missing/invalid. - Reject if attempt receipt
deny_messageis present but empty or >256 chars. - Reject if
receipt_iddoes not equal derivedreceipt_id. - Trust roots are caller-supplied; verifier MUST accept only receipts whose (
trust_root_id,signing_key_id) maps to a known public key.
A Receipt Producer MUST:
- Emit receipts that conform to the schema and all normative requirements.
- Compute canonicalization, hashes, and signatures exactly as specified.
- Include a valid
receipt_idandsignaturefor every receipt.
A Verifier MUST:
- Implement strict verification as defined in 4.11.
- Reject any deviation without fallback or compatibility mode.
- Accept only receipts with known (
trust_root_id,signing_key_id) mappings.
An Executor MUST:
- Accept only EvaluationReceipts with
decision: "ALLOW"for execution. - Link ExecutionReceipts to the parent EvaluationReceipt via
parent_receipt_id. - Emit an AttemptReceipt for any governed action that cannot be evaluated or executed.
- Implementations MUST validate Ed25519 signatures using constant-time operations.
- Private signing keys MUST be protected and never exposed in receipts or logs.
- Demo keys in examples are for demonstration only and MUST NOT be used in production.
- Receipts contain cryptographic proofs; tampering with any field invalidates the signature.
- The
schema_hashbinds verification to a specific schema version; changing the schema requires a protocol version update.
KORZENT_PROTOCOL:"korzent"KORZENT_PROTOCOL_VERSION:"1.0.0"KORZENT_V1_SCHEMA_HASH:sha256:103e0121f3f5b71b9a6a8489feb7159c0e99518f1bb0f5fbee6e1709ec16f40fZERO_HASH:sha256:0000000000000000000000000000000000000000000000000000000000000000
Deterministic test vectors are provided in test-vectors/ with the following files:
| Vector | Kind | Decision | File |
|---|---|---|---|
| eval_deny | EVALUATION | DENY | test-vectors/eval_deny.receipt.json |
| eval_allow | EVALUATION | ALLOW | test-vectors/eval_allow.receipt.json |
| exec_allow | EXECUTION | ALLOW | test-vectors/exec_allow.receipt.json |
| attempt_deny | ATTEMPT | DENY | test-vectors/attempt_deny.receipt.json |
Running the test suite validates these vectors:
npm testCLI verification example using a test vector:
npm run verify -- test-vectors/attempt_deny.receipt.json --trust-root examples/demo_pubkey.txtExpected output: VALID OK