Skip to main content

Integrity Verification

Chronicle can verify the live ledger directly from the database.

Use:

php artisan chronicle:verify

What the verifier checks

Chronicle walks the ledger in stable order:

  1. created_at
  2. id

For each entry it verifies:

  • the canonical payload still hashes to payload_hash
  • the expected chain hash still matches chain_hash
  • any linked checkpoint exists
  • any linked checkpoint signature verifies against the checkpoint chain hash

Failure types

Full verification can fail with:

  • payload_hash_mismatch
  • chain_hash_mismatch
  • checkpoint_missing
  • checkpoint_signature_invalid
  • unknown_key

The command also reports the entry id where corruption begins.

Chronicle v1.11 adds cheaper, scoped verification modes (--checkpoints-only, --since-last-checkpoint, --from-checkpoint/--to-checkpoint, --resume) and an external-anchor pass (--anchors), each with its own failure reasons (checkpoint_chain_broken, checkpoint_head_mismatch, segment_discontinuous, anchor_invalid). See Scalable Verification.

Verifying an entry range (v1.13)

When you have two entries rather than two checkpoints, verifyEntryRange verifies the span between them without your having to work out checkpoint bounds:

use Chronicle\Verification\IntegrityVerifier;

app(IntegrityVerifier::class)->verifyEntryRange($fromSequence, $toSequence);
php artisan chronicle:verify --from=<entry-ulid> --to=<entry-ulid>

Chronicle resolves the signed checkpoints that enclose the range and recomputes the chain between them, so verification of the requested entries rides on the signed anchors - never on a selected entry's own stored hash. It fails closed if the derived anchors don't actually enclose the range. A range extending past the last checkpoint is recomputed to the head, carrying the same trust as --since-last-checkpoint. See Scalable Verification.

Why this differs from export verification

chronicle:verify validates the live ledger in the source system.

chronicle:verify-export validates a portable export dataset.

You usually want both:

  • live verification for operational integrity checks
  • export verification for off-system auditability

Operational use

Run live verification:

  • on a schedule
  • after database restore procedures
  • before or after creating formal exports
  • during incident response if tampering is suspected

Interpreting a failure

When verification fails, the reported entry id is where Chronicle first detects broken integrity. The actual root cause may be that entry or an earlier out-of-band change that cascaded into later chain failures.

That means the failure location is a forensic starting point, not always the full story.