Skip to content

feat(audit): tamper-evident hash-chained audit.log.jsonl #244

@dripsmvcp

Description

@dripsmvcp

What you're trying to do

audit.log.jsonl is "append-only by design" (see CONTRIBUTING) and is the
trust anchor for the review gate — every approve/reject/supersede lands an
AuditEvent. But "append-only" is currently a convention, not a property:
audit.log_event simply opens the file in append mode and writes a JSON line,
and AuditEvent carries no link to the prior event. Any process (a buggy
importer, a malicious agent with filesystem access, a bad merge) can rewrite,
reorder, or delete history and nothing detects it. For a review-gated KB whose
whole pitch is "a human approved this," a tamper-evident log is the natural
backstop.

Suggested shape

  • Extend AuditEvent with prev_hash: str and hash: str, where
    hash = sha256(prev_hash + canonical_json(event_without_hash)) — a Merkle-style
    chain over the log.
  • log_event reads the last line's hash, sets it as prev_hash, computes and
    stores hash. Genesis event uses a fixed zero prev_hash.
  • vouch doctor (or a new vouch fsck check) re-walks the chain and reports the
    first broken link with its line number — audit chain broken at line N.
  • kb.audit optionally returns _meta.chain_ok: bool.

Acceptance

  • Tampering with any historical line (edit a field, delete a line, reorder)
    makes vouch doctor report the exact break point.
  • An untouched log verifies clean; verification is O(n) over the file.
  • Existing logs without hashes are detected and can be sealed forward from the
    current tip (documented one-time migration), so adoption isn't a hard break.

Out of scope

  • Cryptographic signing / external notarization (hash-chaining only here).
  • Encrypting audit entries (that's a visibility/secrecy concern, orthogonal to
    integrity).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions