Skip to content

AuditProof Specification

The AuditProof is a signed, hash-chained JSON document: verifiable evidence of a capsule's full lifecycle, from creation through execution to destruction. This page defines the canonical wire format. (The API resource and version field use the forever-stable cdp identifier.)

Version

Current wire version: cdp_version: "2.1". Verifiers accept 1.0, 2.0, and 2.1. The chain structure, hash algorithm (SHA-512), and signature scheme (Ed25519) are identical across versions; 2.x adds document-level fields additively and never mutates the chain.


Format Overview

An AuditProof contains five sections: metadata, the 8-step hash chain, the final hash, the cryptographic attestation, and context fields.

{
  "cdp_version": "2.1",
  "capsule_id": "cap_a8f3e71c...",
  "created_at": "2026-03-01T14:00:00Z",
  "destroyed_at": "2026-03-01T14:04:58Z",
  "chain": [
    {
      "step": 1,
      "subsystem": "eee_namespace",
      "operation": "environment_isolation",
      "evidence_hash": "sha512:...",
      "chain_hash": "sha512:..."
    },
    {
      "step": 8,
      "subsystem": "capsule_destroy",
      "operation": "lifecycle_completion",
      "evidence_hash": "sha512:...",
      "chain_hash": "sha512:..."
    }
  ],
  "final_hash": "sha512:2c8a4f63d19e7b0a1f3c5d8e9b4a7c6f2d1e0a3b5c8d7e9f4a6b3c1d8e5f7a2b9c0d4e6f1a3b7c5d8e2f9a0b4c6d1e3f5a7b8c0d2e4f6a9b1c3d5e7f8a0b2c4d6",
  "canonical_hash": "sha512:...",
  "attestation": {
    "algorithm": "Ed25519",
    "public_key": "base64:MCowBQYDK2Vw...",
    "signature": "base64:VGhpcyBpcyBh...",
    "key_id": "nrx-verify-20260301T140458Z-a8f3e71c"
  },
  "capsule_context": {
    "jurisdiction": "US",
    "data_classification": "PHI"
  },
  "termination": {
    "trigger": "customer_request",
    "command_was_running": false
  },
  "regulatory_context": {
    "notice": "This mapping identifies regulatory provisions related to the destruction evidence. It is not a compliance certification. Compliance determinations should be made by qualified legal and compliance professionals.",
    "framework_version": "2026-02",
    "jurisdiction": "US",
    "mappings": ["..."]
  },
  "component_proofs": { "...": "sha512:..." }
}

(The example elides six of the eight chain steps and shows placeholder hashes for readability; a real proof always carries all eight steps with full 128-hex-character SHA-512 values.)


Required Fields

These fields must be present for an AuditProof to be valid. Verification rejects proofs missing any of them.

Field Type Description
cdp_version string "1.0", "2.0", or "2.1" — current emission is "2.1"
capsule_id string Capsule identifier
created_at string ISO 8601 timestamp — when the capsule was created
destroyed_at string ISO 8601 timestamp — when destruction completed. Also the timestamp input to every chain-step hash
chain array Ordered chain step objects (see below)
final_hash string SHA-512 value equal to the last chain step's chain_hash
attestation object Ed25519 signature and public key (see below)
canonical_hash string 2.x only — SHA-512 over the document's canonical field view; the signature basis for 2.x proofs

The Eight Chain Steps

A complete AuditProof always carries exactly these eight steps, in this order:

Step subsystem operation (serialized) method (hash input, fixed constant)
1 eee_namespace environment_isolation procfs_verification
2 eee_tmpfs filesystem_isolation mountinfo_verification
3 eee_memory multipass_wipe dod_5220_multipass_wipe
4 dire_keys key_destruction ed25519_key_destruction
5 dire_identity credential_incineration credential_incineration
6 fgx_forensic merkle_zero_state merkle_tree_verification
7 rzl_audit chain_integrity_seal hash_chain_validation
8 capsule_destroy lifecycle_completion capsule_lifecycle_verification

Chain Step Object

Field Type Description
step integer Step number, 1 through 8
subsystem string Step identifier (table above)
operation string Operation performed by the step
evidence_hash string SHA-512 hash of the step's execution evidence
chain_hash string SHA-512 hash linking this step to the previous one

Hash Chain Recomputation

The chain is fully recomputable from the proof document alone — no Nanorix code or network access required:

chain_hash[n] = SHA-512(
    prev_hash ‖ 0x00 ‖ subsystem ‖ 0x00 ‖ "destroy" ‖ 0x00 ‖ method ‖ 0x00 ‖ timestamp
)
  • prev_hash is the previous step's chain_hash hex string (without the sha512: prefix); for step 1 it is the genesis value SHA-512(""): cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
  • ‖ 0x00 ‖ denotes concatenation with a single null byte between elements.
  • "destroy" is a literal action label, identical for every step.
  • method is the step's fixed canonical method constant from the table above. It is part of the specification, not the serialized proof; the serialized operation field is descriptive metadata and is not a hash input.
  • timestamp is the proof's destroyed_at value.
  • final_hash must equal step 8's chain_hash.

An altered step, reordered chain, or edited timestamp changes every downstream chain_hash and breaks the equality — which is what makes the sequence tamper-evident.


Attestation

Field Type Description
algorithm string Always "Ed25519"
public_key string Base64-encoded Ed25519 public key, prefixed with base64:
signature string Base64-encoded Ed25519 signature, prefixed with base64:
key_id string Key identifier — nrx-verify-{timestamp}-{capsule_id_prefix} for ephemeral keys, or a stable authority key id in managed-authority mode

Signature Basis (version-dependent)

  • 1.0 — the signature is computed over the final chain hash's hex string as ASCII bytes (with the sha512: prefix stripped).
  • 2.x — the signature is computed over the document's canonical_hash: a SHA-512 over the canonical (RFC 8785 / JCS) serialization of the proof's fixed field view. Verifiers recompute the canonical form from the document and compare before checking the signature.

Signing Modes

  • Ephemeral (default). Each proof is signed with a fresh Ed25519 keypair minted for that run alone. The private key signs exactly once and is zeroized from memory; the public key is embedded in the proof and registered for optional provenance lookup via GET /v1/keys/:id.
  • Managed authority. Accounts configured with a managed signing authority sign with an authority-held key; such proofs carry signing_authority_id and signing_key_version fields identifying the key lineage. Customer-managed signing keys are also supported in this mode.

Both modes verify identically offline: the public key needed for verification travels inside the proof.


Optional Fields

These fields provide context but are not required for cryptographic verification.

capsule_context

Customer-declared metadata. Nanorix records these declarations verbatim and does not verify them.

Field Type Description
jurisdiction string Customer-declared: "US", "EU", "UK", "CA", "AU", "IN", "OTHER"
data_classification string Customer-declared: "PHI", "PII", "financial", "credentials", "general"

termination

Field Type Description
trigger string "customer_request", "ttl_expired", or "system_restart"
command_was_running boolean Whether a command was executing when destruction began
command_completed boolean Present only if command_was_running is true

regulatory_context

A factual mapping of destruction steps to regulatory provisions, filtered by the customer's declared jurisdiction. See Regulatory Context.

Not a compliance certification

The regulatory_context field identifies regulatory provisions related to the destruction evidence. It is not a compliance certification. Compliance determinations should be made by qualified legal and compliance professionals. The field travels with the proof as reference context; the cryptographic chain and signature cover the proof's evidence fields.

component_proofs

Individual proof hashes from steps that performed real, verifiable operations. Each value is a SHA-512 hash from a specific step's verification.


Partial Proofs

If a capsule cannot complete the destruction sequence (server restart, lost state), a partial proof is generated:

{
  "cdp_version": "2.1",
  "completeness": "partial",
  "reason": "capsule_state_lost_on_restart",
  "chain": []
}

A partial proof carries an empty chain — no destruction steps ran, so there is nothing to chain — and may omit the attestation. A complete proof always carries exactly 8 steps. The completeness field is the discriminator; verifiers reject any proof whose chain is neither empty-and-partial nor exactly 8 steps.


Verification

AuditProofs can be verified three ways:

  1. Offline — recompute the chain from genesis with the formula above, check final_hash equals step 8's chain_hash, recompute the version-appropriate signature basis, and verify the Ed25519 signature with the embedded public_key. Zero network calls.
  2. APIPOST /v1/verify with the proof JSON body. Stateless, no authentication.
  3. Web — drag-and-drop at nanorix.io/verify. Runs entirely client-side.

Step-by-step instructions: Verification.


Versioning

  • 1.0 — original single-document format. Chain + final hash + attestation; signature over the final chain hash.
  • 2.0 — two-layer document: the same chain wrapped in a document carrying canonical_hash (the new signature basis) and signing-authority fields.
  • 2.1 — current. Restores destroyed_at to the serialized document so independent verifiers can recompute chain-step timestamps without any out-of-band data.

Evolution is strictly additive: fields are never removed or renamed, the 8-step chain structure and algorithms (SHA-512, Ed25519) are frozen, and previously issued proofs remain verifiable forever.