Concepts

The Notary

The open-source package that computes and verifies every hash and signature in the Bedrock ledger — used by Bedrock itself, and available to anyone who wants to verify independently.

@bedrockcompliance/notary is the deterministic, key-free core of the Bedrock ledger protocol. It contains the canonical JSON serialiser, the record and chain hash functions, and the ECDSA P-256 signature verifier. Bedrock imports it on both the write path (computing hashes when records are created) and the verify path (checking signatures when certificates are verified), so there is no internal copy of the algorithm that differs from what third parties run.

What lives in the package

Compute (used by the Bedrock writer):

  • canonicalise() — the canonical JSON serialiser that produces the bytes Bedrock signs over.
  • computeRecordHash(payload) — sha256 of the canonicalised record payload.
  • computeChainHash(recordHash, previousHash) — the hash that links each record to its predecessor.

Verify (used by third parties and by Bedrock's verify endpoint):

  • verifyChain(records, firmId) — full chain integrity check.
  • verifySignature(record, options?) — ECDSA P-256 signature verification with optional trusted-key pinning.
  • verifyCertificate({ certificate, record }) — end-to-end certificate check.

Contract:

  • The Signer interface that third-party signing implementations target.
  • GENESIS_HASH, SIGNING_ALGORITHM, ChainInvalidReason constants.

What does NOT live in the package

Anything that holds, uses, or generates a private key. No signing implementations, no KMS bindings, no networking.

Why dogfooding matters

The Bedrock writer calls computeRecordHash and computeChainHash from the notary when creating records. The verify endpoint calls verifySignature from the same package. A contract test in the Bedrock monorepo creates a record with the private signer, then verifies it with the notary — any drift between the two sides fails CI.

Try it

bash
npm install @bedrockcompliance/notary
ts
import { verifyCertificate } from '@bedrockcompliance/notary';

const response = await fetch(
  `https://api.bedrockcompliance.co.uk/v1/verify/${certificateId}`,
);
const { certificate, record } = await response.json();
const result = verifyCertificate({ certificate, record });
console.log(result.valid ? 'verified' : result.reason);

Source

github.com/bedrockcompliance/notary

See also