Skip to content

wfredricks/chainblocks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

chainblocks πŸ–‡οΈ

An immutable, hash-chained audit ledger you can embed in any project.

chainblocks is a small, ownable, embeddable piece of cryptographic plumbing. Any project that needs to say "this happened, in this order, and nothing has been edited since" can import it like SQLite, append typed entries to it, and verify the chain in linear time.

The storage layer is pluggable β€” write to a file, to your application's database, to S3, or to whatever your project already uses for state. The integrity guarantee is in the hash chain, not in the storage.


Who is this for?

  • AI agent and digital twin builders who need defensible audit trails β€” "the system learned this fact at this time from this source; here is the unbroken chain back to the observation"
  • Government and defense teams who need tamper-evident logs that can be authorized (FedRAMP, IL4/5, STIG) without depending on a vendor blockchain
  • Regulated industries (finance, healthcare, supply chain) where audit-trail integrity is a compliance requirement, not a nice-to-have
  • Anyone building agentic systems where the question "did the agent really do that?" is going to be asked β€” in court, in a postmortem, or in a contract dispute

If you have one trusted writer and a need to prove "nothing has been edited since," chainblocks is for you.

If you have many mutually-suspicious writers that need to agree without coordination, you want a blockchain, and chainblocks is not the right tool. We are explicitly the simpler thing.


Why chainblocks?

chainblocks A blockchain Database audit log Plain syslog
Tamper-evident βœ… via hash chain βœ… via consensus ❌ admin can edit ❌ root can edit
Multi-writer ❌ single writer per ledger βœ… many writers βœ… many writers βœ… many writers
Throughput βœ… thousands/sec on a laptop ❌ tens/sec at best βœ… thousands/sec βœ… thousands/sec
Storage substrate βœ… pluggable (file, S3, SQL, …) ❌ on-chain only ⚠️ tied to the DB ⚠️ tied to syslog/journald
Operational complexity βœ… a library ❌ a network ⚠️ DBA expertise βœ… already running
Cross-language verifier βœ… from MODEL.md βœ… usually ❌ none ❌ none
Audit-trail guarantee βœ… verifiable by anyone with the head hash βœ… verifiable on-chain ❌ "trust our DB" ❌ "trust our host"
Trust requirement one honest writer at write-time distributed consensus DB administrator system administrator
Adoption-blocker-class minimal regulatory, operational, performance "this is our audit log of our audit log" nothing is signed

chainblocks is the smallest piece of cryptographic plumbing that gets you a defensible audit trail. No consensus, no mining, no token, no SaaS, no telemetry.


Quick start

npm install @chainblocks/core
import { openLedger, FileStore } from '@chainblocks/core';

// Open or create a ledger
const ledger = await openLedger({
  store: new FileStore({ path: './audit.ledger' }),
  name: 'app-audit',
  writer: 'app',
});

// Append a typed entry
await ledger.append({
  kind: 'app.event.recorded',
  payload: { eventId: 'e-a8c4', actor: 'alice', action: 'login' },
});

// Read entries (with optional filters)
for await (const entry of ledger.read({ kind: 'app.event.*' })) {
  console.log(entry.seq, entry.ts, entry.payload);
}

// Verify the chain
const result = await ledger.verify();
// { ok: true, head: { seq, hash, ts } }
// or
// { ok: false, tamperedAt: 1342, reason: 'hash_mismatch' }

await ledger.close();

And the standalone verifier β€” your assessor's tool:

$ npx chainblocks-verify ./audit.ledger
βœ“ Ledger: app-audit
βœ“ Writer: app
βœ“ Entries: 4,237
βœ“ Head: seq=4236 hash=sha256:8f3a91c2…
βœ“ Chain valid (verified in 47ms)

When the chain is broken, the CLI reports the exact failing seq and the reason:

$ npx chainblocks-verify ./tampered.ledger
βœ— Chain broken at seq=1342
  reason: hash_mismatch
  expected: sha256:8f3a91c2…
  actual:   sha256:def01bc4…

Features

  • πŸͺͺ FT-CB-01 Open/close lifecycle β€” create, open, close, reopen ledgers; concurrent-open protection via O_EXCL lockfile
  • πŸ“ FT-CB-02 Block append β€” atomic append with server-side seq and ts; concurrent calls serialized internally
  • πŸ“œ FT-CB-03 Sequential read β€” async-iterate the chain in seq order; safe to read while appending
  • πŸ” FT-CB-04 Filtered read β€” read by seq range and/or kind pattern (with trailing wildcard)
  • 🎯 FT-CB-05 Head query β€” O(1) access to the current head
  • πŸ”’ FT-CB-06 Random access by seq β€” fetch any block by its sequence number
  • βœ… FT-CB-07 Full-chain verification β€” walk-and-verify with precise tamper reporting (hash_mismatch, prev_mismatch, out_of_order, torn_write, missing_block, malformed_block)
  • ⏩ FT-CB-08 Incremental verification β€” verify from a trust anchor forward for huge ledgers
  • πŸ”Œ FT-CB-09 Store port β€” pluggable storage interface; bring your own backend (Postgres, SQLite, S3, in-memory, …)
  • πŸ’Ύ FT-CB-10 FileStore β€” production default; JSONL on disk with fsync after every append and O_EXCL lockfile
  • πŸ§ͺ FT-CB-11 MemoryStore β€” for tests and ephemeral ledgers; satisfies the Store contract
  • πŸ–₯️ FT-CB-12 Verifier CLI β€” chainblocks-verify <path> standalone tool, no chainblocks knowledge required of the operator
  • πŸ”” FT-CB-13 Append events β€” EventEmitter 'append' hook for live dashboards or replication tail-ers
  • ❗ FT-CB-14 Typed error taxonomy β€” every failure mode is a typed error class with structured context
  • πŸ”’ FT-CB-15 RFC 8785 canonicalization β€” cross-implementation-deterministic hashing; write a verifier in any language and get byte-identical results
  • πŸ—οΈ FT-CB-16 Project-wide quality bar β€” CI gates on tests, typecheck, JSDoc coverage, example runs; performance budgets enforced by benchmarks

See docs/FEATURES.md for the full feature inventory mapped to requirements and use cases.


Documentation

The chainblocks repository is documented at multiple levels of depth.

Narrative (start here):

  • STORY.md β€” why this exists, who it's for, the design doctrine (seven commitments, six explicit non-goals)
  • This README.md β€” the quick pitch

Reference (for integrators):

  • docs/API.md β€” every exported symbol with signature, parameters, returns, throws, and a runnable example
  • docs/USE-CASES.md β€” nine canonical use cases (UC-1 through UC-9) that drove the design
  • docs/FEATURES.md β€” the feature inventory mapped to requirements and use cases
  • REQUIREMENTS.md β€” 65 numbered requirements (REQ-CB-*) the implementation satisfies
  • MODEL.md β€” the portable data-model specification (Block format, canonicalization rule, verification algorithm in pseudocode) β€” sufficient to implement chainblocks in any language

Governance:

  • SECURITY.md β€” supported versions, vulnerability reporting, threat model summary, cryptographic choices
  • docs/SECURITY-MODEL.md β€” deeper threat model: what chainblocks protects against, what it does NOT protect against, trust boundaries, scenarios where chainblocks fails
  • CONTRIBUTING.md β€” how to file issues, run tests, propose changes
  • CODE_OF_CONDUCT.md β€” Contributor Covenant 2.1
  • CHANGELOG.md β€” release-by-release log

Examples:


What chainblocks is NOT

Stated plainly so no one is surprised. From STORY.md's explicit non-goals:

  • ❌ Not a blockchain β€” no consensus, no mining, no token, no network
  • ❌ Not a distributed database β€” single writer per ledger by design
  • ❌ Not an ACID database β€” queries are linear scans; project the log into a database if you need indexed queries
  • ❌ Not a secrets store β€” payloads are stored as supplied; encrypt before append if needed
  • ❌ Not tamper-proof β€” anyone with substrate write access can overwrite, but the chain will detect it. Tamper-EVIDENT, not tamper-PROOF
  • ❌ Not a SaaS β€” chainblocks is a library; there is no chainblocks.io
  • ❌ No telemetry, no network I/O, no phone-home β€” the ledger is the customer's data, in the customer's substrate, under the customer's keys

Status

🚧 Pre-1.0 β€” APIs may change before v1.0.0.

v0.1 is the initial release: the core library, the file/memory store implementations, the verifier CLI, the test pyramid, and the documentation bundle above. v0.2 will add optional plugins for public-blockchain anchoring and Ed25519 per-entry signatures. v1.0.0 follows once external adoption confirms the v0.x API surface.

Semver applies from day one.


License

Apache License 2.0 β€” see LICENSE.

Apache 2.0 was chosen over MIT for the explicit patent grant. chainblocks is targeted at enterprise and government adopters where patent posture matters; the patent grant plus the contributor patent retaliation clause makes adoption decisions cleaner.


πŸ–‡οΈ

About

Embeddable hash-chained append-only ledger. Tamper-evident audit trails for any project.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors