Concepts

The Ledger

An append-only, hash-linked, signed record of every advice decision in your firm.

The ledger is the foundation everything else in Bedrock is built on. Conceptually it is a single linked list per firm. Each entry contains the canonical hash of the advice artefact, the metadata describing it, the previous entry's hash, a strictly monotonic sequence number, and an ECDSA P-256 signature over the record.

Why it's built this way

The FCA does not, and never will, accept “trust us, we've got a database.” The whole value of the ledger comes from the fact that it is impossible for the firm — or Bedrock — to retroactively edit it without the edit being visible to anyone holding any earlier certificate. This is what an immutable system of record actually means.

We get this property by chaining records together: each entry includes the hash of the previous one, and the whole thing is signed. Tampering with any historical entry breaks every certificate issued after it.

What's in an entry

json
{
  "id": "01HX5...",
  "firmId": "01HW1...",
  "sequenceNumber": 184321,
  "eventType": "DOCUMENT_APPROVED",
  "actorId": "01HW2...",
  "actorName": "James Hargreaves",
  "actorFcaRef": "JH123456",
  "documentHash": "9f86d081884c7d65...",
  "documentMetadata": {
    "documentType": "SUITABILITY_REPORT",
    "documentReference": "SR-2026-0142",
    "clientReference": "client-12345"
  },
  "previousHash": "8a3f...",
  "recordHash": "c1d2...",
  "chainHash": "b7e2...",
  "timestamp": "2026-04-07T12:35:01.000Z",
  "signature": "MEUCIQD...",
  "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD..."
}
  • sequenceNumber — strictly monotonic per firm; gaps are detectable.
  • documentHash — SHA-256 of the canonical document bytes (empty string for non-document events).
  • previousHash — the previous record's chainHash verbatim (or GENESIS_HASH for the first entry); binds this entry to its predecessor.
  • recordHash — sha256 over the canonical JSON of this record's payload.
  • chainHash — sha256 of recordHash + previousHash; what the next record will reference as its previousHash.
  • signature — ECDSA P-256 over chainHash using your firm's KMS-held signing key.
  • publicKey — base64-encoded public key in effect at the time the record was signed (so old records remain verifiable across key rotations).
  • documentMetadata — event-specific JSON; round-tripped into certificates.

Why writes are routed through Bedrock and not direct to your DB

The append operation must be performed by something that holds the firm's signing key. That key never leaves the API Lambda's execution context — it's loaded from KMS at cold start, used in-memory, and discarded. If we let firms write to the chain directly, the integrity property would depend on firms keeping their key safe; with Bedrock in the middle, it depends only on AWS KMS access controls.

Verification

Anyone holding your firm's public key can verify any entry — and therefore the entire chain back to genesis — without trusting Bedrock or the firm. The public key is published at:

bash
curl https://api.bedrockcompliance.co.uk/.well-known/signing-key

The verification algorithm is published as an open-source package — see the Notary for the details, or jump straight to Chain integrity for the algorithm walkthrough.

What gets recorded

The full set of ledger event types is defined in the Ledger events reference. The headline ones are:

  • DOCUMENT_SUBMITTED
  • REVIEW_STARTED / REVIEW_COMPLETED
  • DOCUMENT_APPROVED / DOCUMENT_MODIFIED / DOCUMENT_REJECTED
  • IMPACT_ASSESSMENT_APPROVED
  • SLA_BREACHED
  • INCIDENT_LOGGED / INCIDENT_RESOLVED
  • FIRM_SETTINGS_UPDATED

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?