Repository navigation
v0.3.0
Version 0.2.1 was prepared but never tagged or published; its contents are
included here.
Added
- Certificate schema
lethe.cert/3.lethe.cert/1andlethe.cert/2
certificates still validate and verify.key_id— which key epoch signed the certificate, derived from the public
key (ed25519:+ truncated SHA-256). Recomputed and checked at
verification, so a certificate cannot name a key other than its signer.
New reason codeKEY_ID_MISMATCH.audit_head— the audit-chain position the deletion run started from, so
the certificate and the tamper-evident log reference each other.reverifiable— whether the issuer retained what a later re-query needs.timestamp— reserved, currently alwaysnull: a slot for external
corroboration ofissued_at(e.g. RFC 3161) so adding one later needs no
schema v4.
reconcile()/lethe reconcile— compares what a store actually holds
for a subject against what the provenance ledger knows, exposing records that
bypassed the wrapper.--tag-untrackedtags findings for deletion. New
optional connector capabilityscan(), implemented for pgvector.reverify()/lethe reverify— re-checks absence aftervalid_until,
enabled by the newLethe(retain_verification_ids=True).- External anchoring —
lethe anchortimestamps the audit chain head with
an RFC 3161 authority, and records the raw token as a chain entry. Anchoring
the head rather than each certificate covers every recorded event, keeps the
authority out of the deletion path (a TSA outage never blocks a data-subject
request), and costs one call per interval. Closes backdating: an entry cannot
be inserted before an anchored head, and a timestamp dated in the past cannot
be obtained. Optional dependency:pip install 'lethe-delete[anchor]'.
Seedocs/anchoring.md. docs/anchoring.md— choosing an authority (including eIDAS qualified
timestamps), what anchoring does and does not prove, and how to verify a
stored token withopenssl ts.docs/threat-model.md— who must be trusted for a certificate to mean
anything, and what holds against a third party versus a dishonest operator.docs/key-rotation.md— rotation, verifying older certificates, and the
key-compromise case.SECURITY.md— private vulnerability reporting and scope.- CI — GitHub Actions on Python 3.11 and 3.12 against a real Postgres
service, including a guard that fails the build if any test is skipped. - CodeQL — static analysis on pushes, pull requests, and weekly, using the
security-extendedquery suite. The weekly run matters as much as the diff
runs: new queries find issue classes in code that has not changed. - Release workflow — pushing a
v*tag publishes the GitHub Release, with
notes taken from this file. It refuses to publish if the tag disagrees with
lethe/version.py, or if the changelog section is missing or still marked
unreleased, so a tag and its release cannot describe different things.
Changed
- The certificate
claimnow discloses self-issuance inside the signed
payload:issued_atis the issuer's own clock, and the signature proves only
that the key holder produced it. The limitation travels with the artifact. - The claim's re-verify advice is scoped to
reverifiable, rather than
advising an action the default configuration makes impossible.
Fixed
mcp2.x broke the MCP server. Themcpextra declaredmcp>=1.9,
which resolves to 2.x whereFastMCPwas renamed toMCPServer, so
lethe.mcpraisedModuleNotFoundErroron import. Pinned tomcp>=1.9,<2;
migrating to the 2.x API is separate work.- The package version had drifted from the test suite (
test_versionstill
asserted0.1.0after the 0.2.0 release).pyprojectnow derives the
version fromlethe/version.py, so the two cannot diverge. - Two DB tests raised
KeyErrorinstead of skipping when
LETHE_TEST_DATABASE_URLwas unset. - Test isolation: the new retention table is now dropped between tests.