A tamper-evident, append-only, hash-chained ledger. Dependency-free (stdlib only).
Project description
matrym-hashchain
A tamper-evident, append-only, hash-chained ledger. Dependency-free (stdlib only).
Each entry carries a SHA-256 over its own payload and the previous entry's hash, so any later edit, reorder, or deletion of a past record is detected the next time the log is read. It's a file-simple, zero-dependency primitive for audit trails, transaction logs, and chain-of-custody records - the kind of thing a compliance, finance, or records system needs and shouldn't hand-roll.
Install
pip install matrym-hashchain # once released to PyPI
pip install git+https://github.com/MatrymLabs/matrym-hashchain # or straight from GitHub, today
PyPI publishing is wired up via trusted publishing (no stored token); the
pip install matrym-hashchain line goes live with the first tagged release.
Use
from pathlib import Path
from hashchain import append, read, verify, HashChainError
ledger = Path("audit.jsonl")
append(ledger, {"event": "created", "who": "alice"})
append(ledger, {"event": "approved", "who": "bob"})
for entry in read(ledger): # read() verifies the whole chain as it goes
print(entry.seq, entry.payload)
verify(ledger) # True -- the history reads clean end to end
# If anyone edits, reorders, or deletes a past record...
ledger.write_text(ledger.read_text().replace("alice", "mallory"))
verify(ledger) # False
read(ledger) # raises HashChainError: record 0 was tampered ...
The store is plain JSON Lines (.jsonl) - one record per line, human-readable, greppable, and
portable. No database, no daemon, no dependencies.
What it guarantees (and what it doesn't)
This proves integrity, honestly labelled:
| Attack | Detected? |
|---|---|
| A payload was edited | ✅ content-hash mismatch |
| Records were reordered or one was inserted | ✅ sequence / prior-hash mismatch |
| A middle record was deleted | ✅ the next record's prior-hash no longer links |
| The last record(s) were dropped | ❌ not by the chain alone - anchor the head hash elsewhere (a receipt, a second store) if truncation must be caught |
| Who wrote a record (authenticity) | ❌ integrity is not authenticity - sign the head hash (HMAC or a key) to prove authorship |
Any break fails loud with HashChainError rather than returning a dishonest history.
API
append(path, payload) -> Entry- validate, hash-chain, and append one record. Verifies the chain before extending it, so you can't quietly append onto an already-tampered log.read(path) -> list[Entry]- read every record, verifying as it goes. Empty/missing store ->[].verify(path) -> bool-Trueif the ledger reads clean end to end,Falseif broken.content_hash(mapping) -> str- the canonical SHA-256 (sorted keys, no whitespace) the chain uses.Entry(seq, payload, prior_hash, content_hash)- one link;HashChainError- the loud failure.
Provenance
This is a MatrymLabs Hardware Store part: a pattern first proven in the CodeForge MUD engine (the "Chronicle" - the game's tamper-evident memory), then reused across the fleet (a federal guidance-check ledger; an AI-triage decision audit trail). Published standalone so any project can reuse the same tested primitive - one well-made part, many jobs.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file matrym_hashchain-0.1.0.tar.gz.
File metadata
- Download URL: matrym_hashchain-0.1.0.tar.gz
- Upload date:
- Size: 7.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
355377f0f0dd51d2b4307d4058904ddac7a58012e084a30119c31e655fb2fbb7
|
|
| MD5 |
420a1db2c09a8e4ed63669c3d2d3706e
|
|
| BLAKE2b-256 |
ba4f7ab7961a5d7f89fd286c8eb4008ae0a5dca33ed5be1e14eb8a026aa4b6c6
|
Provenance
The following attestation bundles were made for matrym_hashchain-0.1.0.tar.gz:
Publisher:
release.yml on MatrymLabs/matrym-hashchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
matrym_hashchain-0.1.0.tar.gz -
Subject digest:
355377f0f0dd51d2b4307d4058904ddac7a58012e084a30119c31e655fb2fbb7 - Sigstore transparency entry: 2170865591
- Sigstore integration time:
-
Permalink:
MatrymLabs/matrym-hashchain@14677687d8c7ea85ecc9e7bd27e9f618f84f96b7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/MatrymLabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@14677687d8c7ea85ecc9e7bd27e9f618f84f96b7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file matrym_hashchain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: matrym_hashchain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92870e2f084a6f66144ed1baab913f640737f0d09c380d6b118ed068482baf23
|
|
| MD5 |
9829344d48aece3b8664ea6dc5999576
|
|
| BLAKE2b-256 |
1275468424b18c9c42b395f253b073adbb6821bfb454bea493a3505ec7e51396
|
Provenance
The following attestation bundles were made for matrym_hashchain-0.1.0-py3-none-any.whl:
Publisher:
release.yml on MatrymLabs/matrym-hashchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
matrym_hashchain-0.1.0-py3-none-any.whl -
Subject digest:
92870e2f084a6f66144ed1baab913f640737f0d09c380d6b118ed068482baf23 - Sigstore transparency entry: 2170865613
- Sigstore integration time:
-
Permalink:
MatrymLabs/matrym-hashchain@14677687d8c7ea85ecc9e7bd27e9f618f84f96b7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/MatrymLabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@14677687d8c7ea85ecc9e7bd27e9f618f84f96b7 -
Trigger Event:
release
-
Statement type: