---
title: "Integrity"
description: "Optional per-tenant SHA-256 hash chain for tamper evidence."
---

> Documentation Index
> Fetch the complete documentation index at: https://logbun-docs.abshahin.workers.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrity

Set `integrityChain: true` to seal each log with `prevHash` and `contentHash`. Default is `false`.

This is **detection only** — not WORM object storage, not a legal hold.

## Fields

On `LogbunLog` when integrity is on:

- `prevHash` — previous sealed log’s `contentHash`. Genesis is `INTEGRITY_GENESIS` (64 zero hex).
- `contentHash` — SHA-256 hex of `prevHash + '\n' + canonical payload`.

The canonical payload is a stable JSON subset: `id`, `tenantId`, `actorId`, `action`, `entityId`, `oldValues`, `newValues`, `metadata`, `createdAt`. Request decoration (`ipAddress`, `userAgent`) is excluded.

Chains are **per-tenant**. Logs without a tenant use the `__global__` tip.

Root identity fields (`id`, `action`, `actorId`, `createdAt`, `tenantId`, `prevHash`, `contentHash`) are never deleted by `redactPaths`.

## Restore after restart

The per-tenant tip is restored from:

1. Unacked WAL / journal entries (including recovery waves after the bootstrap cap).
2. Then the newest destination row (`query` with `limit: 1`, newest-first).

`logs[0]` is the newest tip. A missing `contentHash` on that row is an empty chain, not genesis from a wrong/older row. Restore fails closed rather than sealing from a truncated recovery prefix.

Destination adapters must persist and round-trip `prevHash` / `contentHash`. Built-in SQLite/Turso/ClickHouse adapters store `prev_hash` / `content_hash` and best-effort `ALTER TABLE` older schemas.

## Verify

`verifyIntegrity` expects an **oldest-first** list:

```ts
import { INTEGRITY_GENESIS } from 'logbun';

const { ok, failedAt, error } = await audit.verifyIntegrity(oldestFirst, {
  genesis: INTEGRITY_GENESIS, // default
});
```

Returns `{ ok, failedAt, error? }`. Failures include `missing integrity fields`, `prevHash mismatch`, and `contentHash mismatch (payload tampered)`.

Source: https://logbun-docs.abshahin.workers.dev/concepts/integrity/index.mdx
