Help us shape the future of Go! Take the 2026 Go Developer Survey

audit

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package audit emits HMAC-signed audit-chain entries for admin mutations. Per gocodealone-multisite SPEC.md T26.

The chain links each entry to the prior entry's signature, so any row mutation invalidates the chain from that point forward. The signing key (MULTISITE_AUDIT_SIGN_KEY) is rotated via the `wfctl multisite audit-rotate` runbook (docs/runbook/backup.md).

In-memory Sink ships here; production wires a postgres-backed Sink via workflow-plugin-audit-chain (separate module).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	ID         int64
	OccurredAt time.Time
	Actor      string // user_id (or "system" for bootstrap entries)
	TenantID   int64  // 0 for cross-tenant ops
	Action     string // "tenant.create", "page.update", etc.
	Subject    string // resource id ("page:42")
	Meta       map[string]any
	PrevSig    string // hex; "" for the first entry
	Sig        string // HMAC-SHA256(prev_sig || canonical(entry))
}

Entry is one audit record.

type Logger

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

Logger produces signed entries + appends them to the configured Sink.

func New

func New(signKey string, sink Sink) *Logger

New returns a Logger. signKey must be non-empty.

func (*Logger) Record

func (l *Logger) Record(actor string, tenantID int64, action, subject string, meta map[string]any) (Entry, error)

Record signs + appends one entry. Always returns the canonical stored copy.

func (*Logger) Verify

func (l *Logger) Verify(tenantID int64) (int, error)

Verify walks the chain returned by Sink.List + returns the first index that breaks (i.e. the first row whose stored Sig does not match the recomputed value). Returns -1 if the whole chain verifies.

type MemorySink

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

MemorySink stores audit entries in-process. Used for tests + local dev.

func NewMemorySink

func NewMemorySink() *MemorySink

func (*MemorySink) Append

func (s *MemorySink) Append(e Entry) (Entry, error)

func (*MemorySink) List

func (s *MemorySink) List(tenantID int64) ([]Entry, error)

type Sink

type Sink interface {
	Append(entry Entry) (Entry, error)
	List(tenantID int64) ([]Entry, error)
}

Sink persists audit entries.

Jump to

Keyboard shortcuts

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