Integrity Certificates
An IntegrityCertificate is a machine-readable cryptographic document that bundles all verification evidence for a single integrity checkpoint. It is modeled on C2PA content credentials and W3C Verifiable Credentials, adapted for AI agent integrity attestation.
Certificates are self-describing: they contain the verdict, the cryptographic proofs, and the URLs needed to verify them. Any party can independently verify a certificate without trusting the Mnemom API.
Certificate Schema
An IntegrityCertificate has four top-level sections: subject, claims, input_commitments, and proofs.
Envelope Fields
| Field | Type | Description |
|---|
@context | string | Always "https://mnemom.ai/aip/v1". Namespace identifier. |
type | string | Always "IntegrityCertificate". |
version | string | Certificate format version. Currently "1.0.0". |
certificate_id | string | Unique identifier in the format cert-{8 random chars}. |
issued_at | string | ISO 8601 timestamp of certificate issuance. |
Subject
Identifies the integrity checkpoint this certificate attests to.
| Field | Type | Description |
|---|
checkpoint_id | string | The integrity checkpoint ID (ic-{uuid} format). |
agent_id | string | The agent that produced the thinking block. |
session_id | string | The session in which the checkpoint was created. |
card_id | string | The Alignment Card used for analysis. |
Claims
The analysis verdict and supporting evidence.
| Field | Type | Description |
|---|
verdict | string | One of clear, review_needed, boundary_violation. |
concerns | array | Array of concern objects, each with category, severity, and description. |
confidence | number | Extraction confidence (0.0-1.0). Reflects provider adapter reliability. |
reasoning_summary | string | Human-readable summary of the analysis reasoning. |
analysis_model | string | The LLM model used for analysis (e.g., "claude-sonnet-4-20250514"). |
analysis_duration_ms | number | Wall-clock time for the analysis in milliseconds. |
Cryptographic commitments to the inputs used for analysis. These enable verification that the analysis was performed over the claimed inputs without revealing the inputs themselves.
| Field | Type | Description |
|---|
thinking_block_hash | string | SHA-256 hash of the thinking block content. |
card_hash | string | SHA-256 hash of the Alignment Card (deterministic JSON). |
values_hash | string | SHA-256 hash of the conscience values array. |
context_hash | string | SHA-256 hash of the window context. |
model_version | string | Analysis model version identifier. |
combined_commitment | string | SHA-256 of all fields concatenated with | separator. |
Proofs
Cryptographic evidence supporting the claims. Contains four proof types.
proofs.signature
Ed25519 digital signature over the signed payload.
| Field | Type | Description |
|---|
algorithm | string | Always "Ed25519". |
key_id | string | Identifier of the signing key. Resolvable via GET /v1/keys. |
value | string | Base64-encoded Ed25519 signature. |
signed_payload | string | The exact JSON string that was signed (deterministic, sorted keys). |
proofs.chain
Hash chain linking this checkpoint to its predecessor in the session.
| Field | Type | Description |
|---|
chain_hash | string | SHA-256 hash of the chain link (includes previous hash, checkpoint ID, verdict, thinking block hash, input commitment, and timestamp). |
prev_chain_hash | string | null | Previous chain hash. null for the first checkpoint in a session. |
position | number | Zero-indexed position in the session chain. |
proofs.merkle
Merkle tree inclusion proof. May be null if the checkpoint has not yet been added to the agent’s Merkle tree.
| Field | Type | Description |
|---|
leaf_hash | string | SHA-256 leaf hash of this checkpoint in the Merkle tree. |
leaf_index | number | Index of this leaf in the tree. |
root | string | Current Merkle root. |
tree_size | number | Total number of leaves in the tree. |
inclusion_proof | array | Array of sibling hashes, each with hash (hex) and position ("left" or "right"). |
proofs.verdict_derivation
Zero-knowledge proof of correct verdict derivation. May be null if no ZK proof has been generated. See Verifiable Verdicts for details.
| Field | Type | Description |
|---|
method | string | Always "SP1-STARK". |
image_id | string | The guest program image ID. |
receipt | string | The STARK proof receipt (base64). |
journal | string | The public journal output (base64). |
verified_at | string | ISO 8601 timestamp of when the proof was verified. |
Verification URLs
Self-contained links for independent verification.
| Field | Type | Description |
|---|
verification.keys_url | string | URL to fetch signing keys: https://api.mnemom.ai/v1/keys |
verification.certificate_url | string | URL to retrieve this certificate. |
verification.verify_url | string | URL to submit this certificate for server-side verification: https://api.mnemom.ai/v1/verify |
The signed_payload field contains the exact JSON string that the Ed25519 signature covers. It is constructed with deterministic key ordering (alphabetically sorted) to ensure the same payload produces the same bytes regardless of property insertion order.
The signed payload includes these fields, sorted alphabetically:
{
"agent_id": "agent-abc123",
"chain_hash": "a1b2c3...",
"checkpoint_id": "ic-550e8400-e29b-41d4-a716-446655440000",
"input_commitment": "d4e5f6...",
"thinking_block_hash": "7a8b9c...",
"timestamp": "2026-02-18T12:00:00.000Z",
"verdict": "clear"
}
The JSON is produced using JSON.stringify(payload, Object.keys(payload).sort()), which ensures keys appear in lexicographic order. This exact string (UTF-8 encoded) is the message passed to Ed25519.sign().
The combined_commitment is computed as follows:
- Each input field is serialized to JSON with recursively sorted keys (deterministic stringify).
- The serialized fields are concatenated with a pipe (
|) separator in this order:
- Card (full Alignment Card object)
- Conscience values array
- Window context array
- Model version string
- Prompt template version string
- The concatenated string is UTF-8 encoded and hashed with SHA-256.
- The result is the hex-encoded hash.
combined_commitment = SHA-256(
deterministicJSON(card) + "|" +
deterministicJSON(conscience_values) + "|" +
deterministicJSON(window_context) + "|" +
deterministicJSON(model_version) + "|" +
deterministicJSON(prompt_template_version)
)
This commitment proves the analysis was performed over specific inputs without revealing the inputs. A verifier who has the original inputs can recompute the commitment and compare.
Verification Instructions
Any party can verify an IntegrityCertificate using the following five steps. Steps 1-4 can be performed offline with the certificate and the public key. Step 5 requires a network call to the prover service.
Step 1: Fetch the Public Key
Retrieve the signing key referenced by proofs.signature.key_id:
curl https://api.mnemom.ai/v1/keys
Find the key entry matching key_id. The public_key field is the hex-encoded Ed25519 public key.
Public keys can be cached. They rotate infrequently, and the is_active field indicates whether a key is currently in use for new signatures.
Step 2: Verify the Ed25519 Signature
Verify proofs.signature.value (base64-encoded) against proofs.signature.signed_payload (UTF-8 string) using the public key from Step 1.
import * as ed from '@noble/ed25519';
const publicKey = hexToBytes(keyEntry.public_key);
const signature = base64ToBytes(cert.proofs.signature.value);
const message = new TextEncoder().encode(cert.proofs.signature.signed_payload);
const valid = await ed.verifyAsync(signature, message, publicKey);
If the signature is invalid, the certificate has been tampered with. Reject it.
Step 3: Recompute and Verify the Chain Hash
Recompute the chain hash from the certificate fields and compare to proofs.chain.chain_hash:
preimage = (prev_chain_hash || "genesis") + "|" +
checkpoint_id + "|" +
verdict + "|" +
thinking_block_hash + "|" +
combined_commitment + "|" +
issued_at
expected = SHA-256(preimage)
If expected !== proofs.chain.chain_hash, the chain link has been altered.
Step 4: Walk the Merkle Inclusion Proof
If proofs.merkle is present, verify that the checkpoint is included in the agent’s Merkle tree:
- Start with
current = proofs.merkle.leaf_hash.
- For each sibling in
proofs.merkle.inclusion_proof:
- If
position === "left": current = SHA-256(sibling.hash + current)
- If
position === "right": current = SHA-256(current + sibling.hash)
- Compare
current to proofs.merkle.root.
If they match, the checkpoint is included in the tree. Cross-reference the root against the agent’s published Merkle root via GET /v1/agents/{agent_id}/merkle-root.
Step 5: Verify the STARK Proof (Optional)
If proofs.verdict_derivation is present, the verdict was proven via an SP1 STARK proof. Verification can be performed:
- Via the API: Submit the certificate to
POST /v1/verify. The API will delegate STARK verification to the prover service.
- Locally: Use the SP1 verifier with the
image_id and receipt from the certificate. See Verifiable Verdicts for details.
Example Certificate
{
"@context": "https://mnemom.ai/aip/v1",
"type": "IntegrityCertificate",
"version": "1.0.0",
"certificate_id": "cert-k7m2x9pq",
"issued_at": "2026-02-18T14:30:00.000Z",
"subject": {
"checkpoint_id": "ic-550e8400-e29b-41d4-a716-446655440000",
"agent_id": "agent-abc123",
"session_id": "sess-def456",
"card_id": "card-ghi789"
},
"claims": {
"verdict": "clear",
"concerns": [],
"confidence": 1.0,
"reasoning_summary": "Agent reasoning is consistent with declared values. No boundary violations detected.",
"analysis_model": "claude-sonnet-4-20250514",
"analysis_duration_ms": 1847
},
"input_commitments": {
"thinking_block_hash": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"card_hash": "f1e2d3c4b5a6f1e2d3c4b5a6f1e2d3c4b5a6f1e2d3c4b5a6f1e2d3c4b5a6f1e2",
"values_hash": "1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b",
"context_hash": "e3d2c1b0a9f8e3d2c1b0a9f8e3d2c1b0a9f8e3d2c1b0a9f8e3d2c1b0a9f8e3d2",
"model_version": "claude-sonnet-4-20250514",
"combined_commitment": "4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e6f1a2b3c4d5e"
},
"proofs": {
"signature": {
"algorithm": "Ed25519",
"key_id": "key-primary-2026",
"value": "MEUCIQD...base64...==",
"signed_payload": "{\"agent_id\":\"agent-abc123\",\"chain_hash\":\"...\",\"checkpoint_id\":\"ic-550e8400-e29b-41d4-a716-446655440000\",\"input_commitment\":\"...\",\"thinking_block_hash\":\"...\",\"timestamp\":\"2026-02-18T14:30:00.000Z\",\"verdict\":\"clear\"}"
},
"chain": {
"chain_hash": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3",
"prev_chain_hash": null,
"position": 0
},
"merkle": {
"leaf_hash": "c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"leaf_index": 0,
"root": "d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5",
"tree_size": 1,
"inclusion_proof": []
},
"verdict_derivation": null
},
"verification": {
"keys_url": "https://api.mnemom.ai/v1/keys",
"certificate_url": "https://api.mnemom.ai/v1/checkpoints/ic-550e8400-e29b-41d4-a716-446655440000/certificate",
"verify_url": "https://api.mnemom.ai/v1/verify"
}
}
Design Influences
The IntegrityCertificate format draws from two established standards:
-
C2PA Content Credentials: The concept of a self-describing, machine-readable credential that bundles claims with cryptographic evidence. C2PA uses this pattern for media provenance; AIP adapts it for AI agent integrity.
-
W3C Verifiable Credentials: The subject/claims/proofs structure and the
@context namespace pattern. The certificate acts as a verifiable credential where the issuer is the Mnemom analysis service and the subject is the integrity checkpoint.
Key differences from these standards: AIP certificates use Ed25519 instead of JWS/JWT, include hash chain and Merkle proofs for ordering and completeness guarantees, and support optional zero-knowledge proofs for computational integrity.
Further Reading