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
- Walk the chain record by record, in order of
sequenceNumber. - 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). - Assert
previousHashequals the previous record'schainHash(GENESIS_HASHfor the first record). - Recompute
chainHashasSHA-256(recordHash + previousHash)and assert it matches the stored value. - Assert
sequenceNumberis exactly one greater than the previous record's. - Verify the ECDSA P-256
signatureoverchainHashusing thepublicKeyembedded 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 hashSIGNATURE_INVALID— the ECDSA P-256 signature failed verificationSEQUENCE_GAP— a sequence number was skippedPREVIOUS_HASH_MISMATCH—previousHashdoes not match the previous record'schainHash
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
# 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/notaryimport { 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 falseFCA 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