> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mnemom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrity Certificates

> Machine-readable cryptographic certificates that bundle all verification evidence for an integrity checkpoint into a single, self-describing document.

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](https://c2pa.org/) and [W3C Verifiable Credentials](https://www.w3.org/TR/vc-data-model-2.0/), 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.                              |

### Input commitments

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](/protocols/aip/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` |

***

## Signed payload format

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:

```json theme={null}
{
  "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()`.

***

## Input commitment computation

The `combined_commitment` is computed as follows:

1. Each input field is serialized to JSON with **recursively sorted keys** (deterministic stringify).
2. 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
3. The concatenated string is UTF-8 encoded and hashed with **SHA-256**.
4. 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`:

```bash theme={null}
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.

<Note>
  Public keys can be cached. They rotate infrequently, and the `is_active` field indicates whether a key is currently in use for new signatures.
</Note>

### 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.

```javascript theme={null}
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:

1. Start with `current = proofs.merkle.leaf_hash`.
2. 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)`
3. 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`](/api-reference/endpoint/get-agents-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`](/api-reference/endpoint/post-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](/protocols/aip/verifiable-verdicts) for details.

***

## Example certificate

```json theme={null}
{
  "@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](https://c2pa.org/)**: 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](https://www.w3.org/TR/vc-data-model-2.0/)**: 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.

***

## See also

* [Verifiable Verdicts](/protocols/aip/verifiable-verdicts) -- Zero-knowledge proofs for verdict derivation
* [AIP Specification -- Attestation](/protocols/aip/specification#16-attestation) -- Protocol-level attestation specification
* [AIP Specification -- Verification](/protocols/aip/specification#17-verification) -- Protocol-level verification specification
* [Security & Trust Model -- Cryptographic Guarantees](/guides/security-trust-model#cryptographic-guarantees) -- How certificates fit into the broader trust model
