audit

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package audit is peerbus's append-only, tamper-evident audit log.

Every appended event is chained: each row's hash is

hash = blake3( prev_hash_bytes || canonical_event_bytes )

where the genesis row chains off blake3("") (the blake3 digest of the empty input). Hashes are stored hex-encoded; the bytes fed into blake3 for the chain link are the *hex string bytes* of the previous hash followed by the raw canonical event bytes, so the link is reproducible from what is stored.

Hash function choice: lukechampine.com/blake3 — a maintained, pure-Go BLAKE3 implementation (no cgo), consistent with the project's pure-Go constraint (modernc.org/sqlite). The borrowed design (sluice) used a blake3 hash-chain audit log; this mirrors it.

Single-writer invariant: the hash chain is only well defined if appends are serialised — concurrent appends would race on "what is the previous hash", fork the chain, and collide on the UNIQUE audit.seq constraint. Appender guards every Append with a mutex so the broker (Task 8) can call it from multiple goroutines while the chain stays a single linear sequence.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Appender

type Appender struct {
	// contains filtered or unexported fields
}

Appender serialises append-only writes to the audit hash-chain. It is safe for concurrent use; every Append is mutually exclusive (the single-writer invariant the chain requires).

func NewAppender

func NewAppender(st *store.Store) *Appender

NewAppender returns an Appender backed by st.

func (*Appender) Append

func (a *Appender) Append(event []byte) (store.AuditRow, error)

Append durably appends one event to the chain and returns the row written. Appends are serialised by a mutex: the chain's "next hash depends on the previous hash" link makes a single writer mandatory. The event bytes are stored verbatim and hashed verbatim (the caller owns canonicalisation).

type Break

type Break struct {
	// Index is the position in the ordered row list where the break was
	// found (0-based).
	Index int
	// Seq is the audit.seq of the offending row (or the expected seq when a
	// row is missing/out of order).
	Seq int64
	// Detail is a human-readable explanation of the break.
	Detail string
}

Break describes the first point at which the chain fails verification.

func Verify

func Verify(st *store.Store) (*Break, error)

Verify walks the whole chain from genesis and recomputes every link. It returns the first break found, or nil if the chain is intact (an empty log verifies clean — genesis is implicit until the first Append).

func (*Break) Error

func (b *Break) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL