audit

package
v1.0.126 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package audit is the admin-action audit trail engine: a bounded in-memory ring (the newest MaxRing entries), optional append-only JSONL persistence with rotation, paginated/time-filtered reads over both, and the Data-Plane → Control-Plane push queue. Extracted from package main's store.go per ADR-0002 (store.go decomposition Phase B).

package main keeps the surfaces: the auditEvent/auditEventDiff request wrappers (actor enrichment from the session cookie), the C2c audit-completion middleware (which observes the wrappers, not this engine), the API handlers, and the CP push loop (which drains/requeues through this package). Two inversion points: the SIEM hook (main wires a closure over its syslog singleton — the forwarder is runtime-configured, so the closure reads it at call time) and the DP-mode flag (set by main's cluster wiring; when on, Add also queues for CP push).

Index

Constants

View Source
const MaxRing = 500

MaxRing bounds the in-memory ring. Tests MUST NOT assert on len() deltas of Get() — under cumulative suites the ring saturates and adding an entry evicts the oldest (see the CLAUDE.md test-authoring pitfall).

Variables

This section is empty.

Functions

func Add

func Add(e Entry)

Add appends an entry to the in-memory ring and, when configured, to the persistent JSONL file, the SIEM hook, and the DP push queue.

func ClearPersistForTest

func ClearPersistForTest()

ClearPersistForTest drops the persistence wiring without closing it (used after a shutdown-hook test has already closed the file, so a later restore or Close cannot double-close).

func Close

func Close() error

Close releases the persistent file handle (best-effort; shutdown hook). Safe when persistence was never initialised.

func DPMode

func DPMode() bool

DPMode reports whether DP-mode queuing is active.

func Init

func Init(path string) error

Init opens path for append-only JSONL persistence with rotation. Existing entries are loaded into the in-memory ring on startup. If path is empty this is a no-op (backwards-compatible). F18: Rotates at 50 MB (same as the system log) to prevent unbounded disk growth.

func PersistActive

func PersistActive() bool

PersistActive reports whether a persistent file handle is wired. Used both by tests (shutdown-hook coverage) and by the admin API (GET /api/stats) to surface a silent Init failure: compare against the caller's own configured path to detect an operator-configured log that fell back to volatile in-memory storage.

func Requeue

func Requeue(events []Entry)

Requeue prepends failed events back into the pending queue so they are retried on the next push interval instead of being lost (newest kept under the cap).

func ResetForTest

func ResetForTest() (restore func())

ResetForTest snapshots and clears the ring + persistence state, returning a restore func. Replaces the pre-extraction pattern of tests swapping the package globals directly.

func SetDPMode

func SetDPMode(on bool)

SetDPMode marks this node as a Data Plane (enables CP push queuing).

func SetPersistForTest

func SetPersistForTest(w io.Writer) (restore func())

SetPersistForTest points JSONL persistence at w (path stays empty so reads keep using the ring), returning a restore func.

func SetSIEM

func SetSIEM(fn func(Entry))

SetSIEM installs the SIEM forwarding hook called after every Add.

func SwapRingForTest

func SwapRingForTest() (restore func())

SwapRingForTest snapshots and clears ONLY the in-memory ring, returning a restore func (persistence state untouched).

Types

type Entry

type Entry struct {
	TS       int64  `json:"ts"`                 // Unix milliseconds
	Time     string `json:"time"`               // human-readable "2006-01-02 15:04:05"
	Actor    string `json:"actor"`              // client IP (or authenticated username)
	Action   string `json:"action"`             // "policy.add" | "blocklist.remove" | …
	Object   string `json:"object"`             // the specific item that changed (human-readable name)
	ObjectID string `json:"objectId,omitempty"` // stable ULID of the changed item, when it has one — survives rename, so an object's audit trail is correlatable by ID (§1 identity seam)
	Detail   string `json:"detail"`             // extra context (never contains credentials)
	Before   string `json:"before,omitempty"`   // JSON snapshot before the change
	After    string `json:"after,omitempty"`    // JSON snapshot after the change
}

Entry captures every configuration change made through the UI/API so operators can answer "Who changed What, and When?" — a core SOC requirement. Actor is the client IP of the UI caller, enriched with the authenticated admin identity when available. Action follows a "resource.verb" naming scheme (e.g. "policy.add").

func Drain

func Drain() []Entry

Drain returns and clears the pending audit event queue.

func Get

func Get() []Entry

Get returns a newest-first snapshot of the in-memory ring.

func GetMemory

func GetMemory(offset, limit int, fromTS, toTS int64) (page []Entry, total int)

GetMemory returns paginated, optionally time-filtered entries from the in-memory ring (newest-first).

func GetPersistent

func GetPersistent(offset, limit int, fromTS, toTS int64) (page []Entry, total int)

GetPersistent reads the JSONL audit log file with pagination. Returns entries newest-first. If from/to are non-zero, filters by timestamp. Falls back to the in-memory ring if no file is configured.

Jump to

Keyboard shortcuts

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