Decision Certificates
Every governance decision EVE CoreGuard makes is a signed, verifiable record — not just a log entry. A Decision Certificate is a cryptographically bound document that proves exactly what was decided, by which policy version, at what time, and why. This page explains what a certificate contains, how it is signed, how to verify it independently, and how long to retain it for regulatory purposes.
Contents
What Is a Decision Certificate?
When you call POST /v1/decisions/evaluate, EVE CoreGuard does two things: it evaluates the action against the requested policy pack, and it generates a Decision Certificate that permanently records that evaluation. The certificate is issued regardless of whether the decision is ALLOWED, BLOCKED, or MODIFIED — every governance decision has a certificate.
The certificate's purpose is regulatory proof. If your organization is audited by a financial regulator, a healthcare compliance officer, or a state attorney general, the certificate is the evidence that your AI system applied governance controls before the output reached an end user. The cryptographic signature on every certificate (Ed25519 in production; HMAC-SHA256 in legacy mode) makes it tamper-evident — any post-hoc modification of the decision record invalidates the signature, providing mathematical proof of record integrity.
Decision Certificates differ from conventional audit logs in three critical ways:
- Signed at issuance — The signature is computed at decision time, not appended retroactively. There is no window in which a valid certificate can be produced for a decision that did not actually occur.
- Self-describing — Every certificate carries the policy version, the governance disposition, the risk score, and a signed digest of the rule-result set (
rule_results_sha256). The signed record binds these values; the full rule-result array and the policy-artifact bytes are provided in the accompanying evidence bundle rather than always inline, so a certificate can be interpreted without a live call to EVE Core but the underlying rule-result and policy artifacts are referenced by digest. - Third-party verifiable — Ed25519 verification requires only the certificate, the verification profile below, and EVE's published public key. EVE Core does not need to be online or consulted. Note the distinction: a certificate being verifiable by any third party is not the same as it having been verified by an independent party — the latter requires an external auditor, customer, or transparency witness to actually run the check.
Certificate Signing Process
In production, each Decision Certificate is signed with Ed25519 — an asymmetric signature that any third party (your auditor or a regulator) can independently verify against EVE's published public key (/.well-known/eve-pubkey) with no shared secret. The verifier holds only the public key and cannot forge a certificate. A valid signature establishes tamper-evidence and origin against the supplied or pinned key; it does not, by itself, establish the truth of every upstream input or full runtime integrity, and CoreGuard's verdict is a statement of policy admissibility, not final business approval. Signatures are self-describing (tagged ed25519- / hmac-), so a mixed corpus stays verifiable across a key-rotation boundary. External independent verification by a third party has not yet been performed.
A legacy HMAC-SHA256 mode (documented below) is also supported for internal, tenant-scoped integrity using a symmetric key. HMAC proves integrity only to a party that already holds the same secret — it is not a third-party proof and should not be presented as publicly verifiable evidence. For external audit, use the Ed25519 records and the public key.
EVE Decision Evidence — schema eve.decision.v3, the current authoritative certificate contract. The record carries payload_schema: "eve.decision.v3" and audit_schema: "3". Two canonicalizations apply — one for the record content hash, one for the bound content digests:
Schema: eve.decision.v3 (payload_schema; audit_schema "3")
Record content hash eve-jsonc-v1
Serialization: json.dumps(signed_payload, sort_keys=True, default=str) # Python default
Separators: ", " and ": " (a single space after each — NOT compact)
Unicode: ensure_ascii=true (non-ASCII escaped as \uXXXX)
Excluded fields: "hash", "signature", and unsigned metadata (see table)
Evidence hash: "sha256-" + sha256(canonical_bytes).hexdigest()
Signed message: the UTF-8 bytes of the "sha256-<hex>" hash string
Signature: Ed25519 (asymmetric, independently verifiable)
Content digests eve-request-v1 / eve-response-v1 (bind request / model output / rule results)
Serialization: json.dumps(obj, sort_keys=True, separators=(",",":"), ensure_ascii=True, default=str) # COMPACT
Digest: "sha256-" + sha256(canonical_bytes).hexdigest()
Bound into: request_payload_sha256 / response_payload_sha256 / rule_results_sha256 (signed fields)
The record hash uses eve-jsonc-v1 — a deterministic JSON format that is not RFC 8785 JCS: JCS removes all whitespace; eve-jsonc-v1 keeps the single spaces that Python's default json.dumps emits. The content-digest canonicalization (eve-request-v1 / eve-response-v1) is the compact form (no spaces). Using the wrong form produces a different hash and verification fails.
The Ed25519 signing process follows these steps:
Take the signed-payload fields (every field except hash and signature) and serialize them with json.dumps(payload, sort_keys=True): keys sorted lexicographically, a single space after each comma and colon (Python's default separators), ensure_ascii=true so non-ASCII is escaped as \uXXXX. This is the eve-jsonc-v1 canonicalization.
Compute sha256 over the canonical UTF-8 bytes and prefix the lowercase hex digest with sha256-. This sha256-<hex> string is the certificate's Evidence Hash.
Ed25519 signs the ASCII bytes of the Evidence Hash string (not the raw canonical payload bytes) with the deployment's private key, stored in an HSM-backed key management system and never exposed in any component or API response. The hex-encoded signature is stored in the signature field, tagged ed25519-; key_id records the key version for rotation. A legacy hmac- mode signs the same hash string with a symmetric key for internal tamper-evidence only.
When persisted, each certificate is anchored in the organization's append-only audit chain, recorded in the chain_previous_hash / chain_entry_hash / chain_tree_head / chain_sequence coordinates. These chain coordinates are unsigned metadata — they are not part of the eve.decision.v3 signed-field contract, so the certificate signature alone does not prove chain inclusion. Chain integrity (detecting deletion or reordering) is a separate verification over the chain state, not part of offline signature verification of a single certificate.
Key rotation: Signing keys can be rotated without invalidating historical certificates. Each certificate records the key_id used to sign it. To verify historical certificates after a key rotation, provide the historical key version to the verification function. Enterprise key management documentation is available on request — contact our team.
Certificate Schema Reference
The eve.decision.v3 decision record is returned in the audit field of every POST /v1/decisions/evaluate response. The Signing status column states, for each field, whether it is part of the signed-field contract (covered by the Ed25519 signature via the record content hash), a signed digest that binds external content, or unsigned metadata. Only the fields marked Signed are covered by the signature.
| Field | Type | Signing status | Description |
|---|---|---|---|
| audit_id | string | Signed · required | Unique decision-record identifier. Example: audit_<12-hex>. |
| request_id | string | Signed · required | The caller-supplied request identifier for this evaluation. |
| decision | string (enum) | Signed · required | Policy-admissibility outcome: ALLOWED, BLOCKED, or MODIFIED. Not a business decision. |
| governance_verdict | string (enum) | Signed · required | Normalized verdict: ALLOW / BLOCK / MODIFY. |
| response_disposition | string (enum) | Signed | Disposition of the model output: RELEASE or WITHHELD. |
| response_released | boolean | Signed | Whether the model output was released to the caller. |
| business_decision | string | Signed | Always NOT_MADE — CoreGuard governs policy admissibility; it does not make the underlying business decision. |
| request_payload_sha256 | string (sha256-) | Signed digest — binds request content | SHA-256 of the exact request (canonicalization eve-request-v1). The signature binds this digest, so a holder of the original request can prove it produced this decision; the raw request is not in the certificate. |
| request_canonicalization | string | Signed | Canonicalization used for the request digest: eve-request-v1. |
| response_payload_sha256 | string (sha256-) | Signed digest — binds model output | SHA-256 of the exact model output (eve-response-v1). Binds the governed model output by digest, not plaintext. |
| response_canonicalization | string | Signed | Canonicalization used for the response digest: eve-response-v1. |
| rule_results_sha256 | string (sha256-) | Signed digest — binds rule outcomes | SHA-256 over {"decision": …, "violations": [sorted rule IDs]}. The signature binds the decision and the sorted rule IDs that fired — not the human-readable rule descriptions, which are unsigned unless they are part of this digest preimage. |
| signature_key_id | string | Signed | Key ID (kid) of the signing key, e.g. ed25519:<b64url16>. Binds key identity into the signature; a verifier derives the same kid/fingerprint from the public key and checks consistency. |
| charter_hash | string | Signed | Digest of the governance charter artifact in force for this decision. |
| policy_version | string (sha256:) | Signed | Version hash of the policy set. (The policy-set name is unsigned metadata carried elsewhere in the response.) |
| payload_schema | string | Signed | Schema label: eve.decision.v3. |
| audit_schema | string | Signed | Numeric schema version: "3". |
| violations | integer | Signed | Count of rules that fired. |
| risk_score | number | Signed | Composite risk score. |
| timestamp | string (ISO 8601) | Signed · required | UTC timestamp of the evaluation. |
| org_id | string | Signed | Tenant identifier scoping the certificate to your audit namespace. |
| hash | string (sha256-) | Unsigned — output; required for verification | The eve-jsonc-v1 content hash the signature is computed over. Recomputed by a verifier and compared. |
| signature | string (tagged hex) | Unsigned — output; required for verification | Ed25519 signature over the UTF-8 bytes of the hash string. Tagged ed25519- (asymmetric, independently verifiable) or, in legacy mode, hmac- (symmetric, internal tamper-evidence only). |
| decision_trace | array | Unsigned — informational | Human-readable evaluation steps. Not covered by the signature. |
| chain_previous_hash | string (hex) | Unsigned metadata | Hash of the preceding chain entry. Not in the signed-field contract; the signature does not prove chain inclusion. |
| chain_entry_hash / chain_tree_head / chain_sequence | string / string / integer | Unsigned metadata | Decision-chain anchoring coordinates recorded at persistence. Verified separately over the chain state, not by single-certificate signature verification. |
Full Certificate Example (eve.decision.v3)
A sanitized, independently verifiable sample. Scenario: an autonomous agent requested a capability outside its declared envelope and an action exceeding its blast-radius limit; CoreGuard blocked autonomous execution and queued mandatory human review. Signed fields are covered by the signature; hash/signature/decision_trace and the chain_* coordinates are unsigned.
Verify this sample offline with the public key
ed25519:zb1bX3Y_eHJIsB1q
(fingerprint sha256:cdbd5b5f763f787248b01d6a4a0a7e8fde73ad18e2d5b4942d5a2822d8a79fd2).
Two self-contained sample verifiers are provided — Python (verify_certificate.py) and Node
(node verify_certificate.mjs) — and two additional vendor-reproduced cross-checks exist:
the eve-coreguard SDK verifier and the standalone repository verifier
(scripts/verify_eve_decision.py).
Offline Verification
Decision Certificates are designed to be verified without a network connection and without calling any EVE CoreGuard API. Verification requires:
- The full signed evidence record (as received or stored).
- For Ed25519 records: EVE's published public key from
/.well-known/eve-pubkey(no shared secret).
Verification procedure (schema eve.decision.v3):
- Record hash. Take the signed-field payload (every Signed field from the schema table — not
hash,signature, or unsigned metadata), serialize witheve-jsonc-v1(json.dumps(payload, sort_keys=True, default=str)— sorted keys, a single space after each comma and colon,ensure_ascii=true; do not strip the whitespace), compute"sha256-" + sha256(canonical_bytes).hexdigest(), and compare to the record'shash. - Signature. Verify the Ed25519
signatureover the UTF-8 bytes of thatsha256-<hex>hash string, against the published public key. A match establishes tamper-evidence and origin against that key — it does not establish the truth of upstream inputs. (Legacyhmac-records are checked with the shared HMAC key — internal tamper-evidence only, not third-party proof.) - Key identity. Derive the public-key fingerprint (
sha256(SPKI DER)) andkid(ed25519:+ base64url of that digest, first 16 chars) from the supplied public key, and confirm they match the certificate'ssignature_key_id, the published fingerprint, and — where both are supplied — that the PEM and JWK describe the same key. To attribute a certificate to EVE, pin EVE's fingerprint out-of-band. - Content binding. When you hold the original inputs, recompute the request, model-output, and rule-results digests with the compact
eve-request-v1/eve-response-v1canonicalization and confirm they match the signedrequest_payload_sha256,response_payload_sha256, andrule_results_sha256. This proves those exact inputs produced this decision.
A verifier should report these checks individually (schema recognized, signature valid, hash reproduced, fingerprint derived and matched, kid matched, PEM/JWK matched, each digest matched or not evaluated) rather than a single "fully verified" result, and must fail visibly on any modified signed field, signature, key, fingerprint, or digest preimage.
Chain verification is separate and unsigned: the chain_previous_hash / chain_entry_hash / chain_tree_head / chain_sequence coordinates are not part of the signed-field contract, so a valid certificate signature does not prove chain inclusion. Chain integrity (detecting deletion or reordering) is a distinct check over the append-only chain state, performed by the repository chain verifier — not by offline signature verification of a single certificate.
Compliance Retention Guidance
How long you retain Decision Certificates depends on the regulatory regimes that govern your AI deployment. The following table summarizes minimum retention requirements by regulatory domain.
| Regulatory Domain | Authority | Minimum Retention | Notes |
|---|---|---|---|
| Consumer Lending (ECOA / Reg B) | CFPB / Fed | 25 months | Adverse action records; Reg B § 202.12. Retain from date of action, not from credit application. |
| Consumer Reporting (FCRA) | CFPB / FTC | 5 years | For AI systems using consumer reports. Permissible purpose documentation. |
| Mortgage (HMDA) | CFPB | 3 years | Loan application register records under Reg C. |
| Securities / Trading (FINRA) | FINRA / SEC | 7 years | Books and records rules (FINRA Rule 4511, SEC Rule 17a-4). Governance decisions related to trading activity. |
| Healthcare (HIPAA) | HHS OCR | 6 years | From date of creation or last effective date. BAA terms may require longer retention. |
| Insurance (State) | State DOI | 5–7 years | Varies by state. Underwriting records typically 5 years; claims-related AI decisions 7 years in most jurisdictions. |
| Federal Government (NARA) | NARA / OMB | 7+ years | Per agency records schedule. AI decision records may qualify as program records requiring permanent retention in some agencies. |
| General Enterprise | SOX / internal | 7 years | SOX Section 802 general records standard for public companies. Internal policy may require longer. |
EVE Core recommendation: Retain all Decision Certificates for a minimum of 7 years regardless of regulatory domain. This matches the most stringent common requirement (FINRA / SOX) and eliminates the operational complexity of maintaining domain-specific retention schedules. For highly regulated deployments, retain indefinitely and rely on storage compression — certificate records are compact (typically under 2 KB each) and compressible.
Python Verification Example
The eve-coreguard Python SDK (PyPI, v0.2.0) includes a built-in offline verifier. The example below is a minimal, standalone check of the record hash + Ed25519 signature for an eve.decision.v3 record, using only cryptography plus the standard library. It intentionally verifies only those two properties (signature integrity). It does not by itself check key identity or reproduce the request / model-output / rule-results digests — for the full per-field verification (key-identity checks and content-digest reproduction, with individual PASS/FAIL statuses) use the two self-contained sample verifiers verify_certificate.py and node verify_certificate.mjs, or the standalone repository verifier scripts/verify_eve_decision.py.
Using the EVE CoreGuard Python SDK (v0.2.0), the offline verifier eve_coreguard.evidence.verify_decision_record() performs the full eve.decision.v3 check (hash, signature, and the signed content digests). The decision chain is a separate, unsigned mechanism: chain-inclusion integrity is verified over the append-only chain state by the repository chain verifier, not by single-certificate signature verification.
Security note: Never transmit your HMAC verification key over the network or store it in application code. Use an HSM, secrets manager (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault), or encrypted key store. The verification_key_hex parameter in the SDK can be loaded from an environment variable or a secrets manager at runtime.