audit

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package audit provides append-only tamper-evident audit chain storage. It depends only on store.Store and has no keeper or bbolt import.

Index

Constants

View Source
const EventTypeKeyRotationCheckpoint = "key_rotation_checkpoint"

EventTypeKeyRotationCheckpoint marks a key-rotation boundary in the chain. Events before the checkpoint are verified with the old signing key; events after are verified with the new signing key. History is never rewritten — the checkpoint is the trust bridge.

Variables

View Source
var ErrChainBroken = errors.New("audit chain integrity check failed")

ErrChainBroken is returned when audit chain integrity verification fails.

Functions

func KeyFingerprint

func KeyFingerprint(key []byte) string

KeyFingerprint returns a short proof-of-possession token for key. Used in checkpoint events to prove the old and new keys without revealing them.

Types

type Event

type Event struct {
	ID           string    `json:"id"`
	BucketID     string    `json:"bucket_id"`
	Scheme       string    `json:"scheme"`
	Namespace    string    `json:"namespace"`
	Seq          int64     `json:"seq"`
	EventType    string    `json:"event_type"`
	Details      []byte    `json:"details"`
	Timestamp    time.Time `json:"timestamp"`
	PrevChecksum string    `json:"prev_checksum"`
	Checksum     string    `json:"checksum"`
	HMAC         string    `json:"hmac,omitempty"`
}

Event is an append-only audit record with chain integrity.

The chain is secured at two levels:

Checksum — SHA256 over prevChecksum, ID, BucketID, Scheme, Namespace, Details, EventType, and Timestamp. Detects content modification and cross-bucket transplantation. Seq is excluded so it can be assigned inside the write transaction after the caller has computed the hash.

HMAC — HMAC-SHA256 over all fields including Seq. Provides authentication: only a holder of the signing key can produce a valid HMAC. When no signing key is configured the HMAC field is empty and VerifyIntegrity skips HMAC checking.

func (*Event) ComputeChecksum

func (e *Event) ComputeChecksum(prevChecksum string) string

ComputeChecksum returns SHA256(prevChecksum | ID | BucketID | Scheme | Namespace | Details | EventType | Timestamp). Seq is intentionally excluded — it is assigned by Append inside the transaction after the caller computes the checksum.

func (*Event) ComputeHMAC

func (e *Event) ComputeHMAC(key []byte) string

ComputeHMAC returns HMAC-SHA256 over all event fields using key. Returns "" when key is empty — callers interpret that as "no signing key".

func (*Event) VerifyChecksum

func (e *Event) VerifyChecksum() bool

VerifyChecksum returns true when e.Checksum matches the computed value.

func (*Event) VerifyHMAC

func (e *Event) VerifyHMAC(key []byte) bool

VerifyHMAC returns true when the event's HMAC is valid for key. Returns true unconditionally when key or e.HMAC is empty.

type Store

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

Store handles audit event persistence.

func New

func New(db store.Store, signingKey []byte) *Store

New creates an audit Store. Pass a non-nil signingKey to enable HMAC signing of every appended event and HMAC verification in VerifyIntegrity. Pass nil to disable signing.

func (*Store) Append

func (a *Store) Append(scheme, namespace string, event *Event) error

Append writes event to the chain for scheme/namespace. Seq is assigned atomically inside the write transaction.

func (*Store) Init

func (a *Store) Init() error

Init creates the root audit bucket if it does not exist.

func (*Store) LastChecksum

func (a *Store) LastChecksum(scheme, namespace string) string

LastChecksum returns the checksum of the most recently appended event, or "" if no events exist for this scheme/namespace.

func (*Store) LoadChain

func (a *Store) LoadChain(scheme, namespace string) ([]*Event, error)

LoadChain returns all events for scheme/namespace ordered by Seq ascending.

func (*Store) Prune

func (a *Store) Prune(scheme, namespace string, olderThan time.Duration, keepLastN int) error

Prune removes events from the chain, always trimming the oldest end so the surviving events form a contiguous tail. The chain index is rewritten after deletion so LastChecksum remains consistent with stored data.

olderThan: events with Timestamp older than time.Now()-olderThan are candidates for deletion. Pass 0 to make all events candidates. keepLastN: always preserve the most recent keepLastN events by Seq.

func (*Store) VerifyIntegrity

func (a *Store) VerifyIntegrity(scheme, namespace string) error

VerifyIntegrity checks the entire chain for scheme/namespace.

At key-rotation checkpoint events the active verification key switches to the new epoch key. This preserves the chain's tamper-evidence across key rotations without rewriting any historical events.

Jump to

Keyboard shortcuts

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