Features

Chain integrity

On-demand proof that the ledger has not been tampered with — verifiable by anyone, anywhere, without trusting Bedrock.

Chain integrity is the property that makes the ledger worth anything. If the chain could be silently rewritten, every certificate it backs becomes worthless. The integrity check is the algorithm that proves it cannot be.

The verification algorithm

  1. Walk the chain record by record, in order of sequenceNumber.
  2. When the full record payload is available, canonicalise it, hash it with SHA-256, and assert the result equals the stored recordHash (detects field-level tampering).
  3. Assert previousHash equals the previous record's chainHash (GENESIS_HASH for the first record).
  4. Recompute chainHash as SHA-256(recordHash + previousHash) and assert it matches the stored value.
  5. Assert sequenceNumber is exactly one greater than the previous record's.
  6. Verify the ECDSA P-256 signature over chainHash using the publicKey embedded in the record (records carry the key in effect at the time they were signed, so the chain remains verifiable across key rotations).

If any step fails, the failure is one of the four ChainInvalidReason values:

  • HASH_MISMATCH — a stored hash does not match the recomputed hash
  • SIGNATURE_INVALID — the ECDSA P-256 signature failed verification
  • SEQUENCE_GAP — a sequence number was skipped
  • PREVIOUS_HASH_MISMATCHpreviousHash does not match the previous record's chainHash

On-demand verification

Bedrock runs the verification on a daily schedule via an EventBridge-triggered Lambda worker. Each run walks every firm's chain, persists the result to the ChainVerification table, and emits CloudWatch metrics. Any failure triggers an alarm. The Ledger dashboard also surfaces the result on the home page.

Tamper detection & recovery

When verification detects a problem, the integrity dashboard shows the exact discrepancy — a field-by-field diff between the database row and the immutable S3 backup. Firm admins and lead reviewers can restore the original record from the backup, which writes a CHAIN_REPAIRED audit entry to the ledger and automatically re-verifies the chain.

Verifying yourself

bash
# Fetch integrity status (includes verification history)
curl https://api.bedrockcompliance.co.uk/v1/ledger/integrity \
  -H "X-Bedrock-Key: bk_live_..."

# Trigger a fresh verification
curl -X POST https://api.bedrockcompliance.co.uk/v1/ledger/integrity/verify \
  -H "X-Bedrock-Key: bk_live_..."

# Or verify independently using the open-source notary
npm install @bedrockcompliance/notary
typescript
import { verifyChain, computeRecordHash, canonicalise } from '@bedrockcompliance/notary';

// Pass full records with payload for field-level verification
const result = verifyChain(
  records.map(r => ({
    id: r.id,
    sequenceNumber: r.sequenceNumber,
    recordHash: r.recordHash,
    chainHash: r.chainHash,
    previousHash: r.previousHash,
    signature: r.signature,
    publicKey: r.publicKey,
    payload: {
      firmId: r.firmId,
      sequenceNumber: r.sequenceNumber,
      eventType: r.eventType,
      // ... all payload fields
    },
  })),
  firmId,
);

console.log(result.isValid); // true or false

FCA mapping

  • SYSC 9 — Record-keeping integrity
  • PRIN 2A.6 — Cross-cutting obligation to act in good faith
  • SUP 9 — Records to be available to the FCA

See also

Bedrock AIAsk me anything about Bedrock

Hi! I'm Bedrock's AI assistant. I can answer questions about the product, pricing, compliance coverage, and integrations. What would you like to know?