nexart.iodocs

    Governed Execution Quickstart

    Seal a governed CER locally, verify it, run stateless verification, attest it through the production Node and verify the receipt independently.

    @nexart/governed-execution0.4.2NexArt Node0.30.1

    1. Install

    npm install --save-exact @nexart/governed-execution@0.4.2

    Pin the exact version so verification is reproducible.

    2. Configure

    .env (placeholders only)
    # Production canonical Node. This is production, not staging.
    NEXART_NODE_ENDPOINT=https://node.nexart.io
    # Temporary key from your secret manager. Never commit a real key.
    NEXART_API_KEY=<TEMPORARY_API_KEY>

    3. Seal and verify locally

    The producer supplies a complete CAGE AttestationBundle and, optionally, a GraphTopology. Sealing validates the evidence and throws on invalid input (for example TOPOLOGY_ERROR: UNKNOWN_NODE).

    seal.ts
    import {
      CAGE_GOVERNANCE_PROFILE,
      sealGovernedExecution,
      verifyGovernedExecution,
      type AttestationBundle,
      type GraphTopology,
    } from "@nexart/governed-execution";
    
    declare const bundle: AttestationBundle;          // produced by your workflow
    declare const topology: GraphTopology | undefined; // optional
    
    export const cer = sealGovernedExecution(
      { profile: CAGE_GOVERNANCE_PROFILE, evidence: { bundle, ...(topology ? { topology } : {}) } },
      { createdAt: "2026-10-01T09:00:06.000Z" }, // part of certificate identity
    );
    
    const local = verifyGovernedExecution(cer);
    if (!local.ok) throw new Error(`${local.code}: ${local.errors.join("; ")}`);
    // local.stateHashVerification === "not-performed" is expected, not a failure.

    4. Stateless verification

    POST /v1/cer/verify takes { bundle }. It does not persist, publish or sign. HTTP 200 means the operation completed; read status and reasonCode for the verdict.

    const res = await fetch(`${process.env.NEXART_NODE_ENDPOINT}/v1/cer/verify`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ bundle: cer }),
    });
    const v = await res.json();
    // v.status: "verified" | "failed"; v.reasonCode: "OK" | "TOPOLOGY_ERROR" | ...
    // v.governedVerification mirrors the SDK result layers.
    if (v.status !== "verified") throw new Error(v.reasonCode);

    Observed production response for the sample CER on the schema page (abridged):

    {
      "status": "verified",
      "reasonCode": "OK",
      "checks": {
        "certificateIntegrity": "valid",
        "cageSchemaValidity": "valid",
        "causalGraphValidity": "valid",
        "topologyValidation": "valid",
        "resourceSafety": "valid",
        "signature": "skipped"
      },
      "classification": "VERIFIED",
      "node": "nexart-node-prod-1",
      "governedVerification": {
        "stateHashVerification": "not-performed",
        "producerAuthentication": "not-performed",
        "completeness": "not-claimed"
      }
    }

    signature: "skipped" is correct for an unattested CER.

    5. Authenticated attestation

    The body is the complete sealed CER itself, not { bundle }. Neither kid nor nodeId is sent; the Node selects its signing key.

    const att = await fetch(`${process.env.NEXART_NODE_ENDPOINT}/api/attest`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.NEXART_API_KEY}`,
        // Optional: "X-NexArt-Visibility": "private" | "public". Omitted -> "hidden".
      },
      body: JSON.stringify(cer), // the sealed CER, unwrapped
    });
    if (att.status === 401) throw new Error("Missing or invalid API key");
    const attestation = await att.json();
    if (!att.ok) throw new Error(`${attestation.error}: ${attestation.reasonCode ?? ""}`);
    // attestation.ok === true
    // attestation.receipt, attestation.signature                      (receipt + Ed25519 signature)
    // attestation.verificationEnvelope, .verificationEnvelopeSignature (v2 projection signature)
    // attestation.governedVerification                                 (nine-key report)
    // attestation.visibility                                           ("hidden" by default)
    // The CER is NOT returned. Keep your sealed copy.

    Full redacted request and response, field reference and failure codes: Governed Attestation Contract.

    6. Verify independently

    1. Recompute certificateHash (RFC 8785 JCS, SHA-256) with verifyGovernedExecution(cer).
    2. Fetch GET /.well-known/nexart-node.json and select the key whose kid equals receipt.attestorKeyId.
    3. Verify signature: Ed25519 over UTF8(JCS(receipt)), the whole receipt, base64url-decoded.
    4. Verify verificationEnvelopeSignature: Ed25519 over UTF8(JCS({ attestation, bundle })), the whitelisted projection. Not over the envelope descriptor.
    5. Check that receipt.certificateHash equals your CER's hash and receipt.protocolVersion equals its version.

    Step-by-step code: receipt and envelope procedures. Do not treat a Node ok field as independent verification.

    7. Persistence is not publication

    A successful attestation is stored with visibility hidden. It is not public. The returned verificationUrl is formatted, not checked, so do not present it as a public record until you have confirmed it resolves. Full rules: persistence versus publication.