audit

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package audit provides an append-only, tamper-evident record of every action the agent attempts — the accountability backbone for the autonomy ladder.

Records are written as JSON lines, each carrying the SHA-256 hash of the previous record (a hash chain). Any insertion, deletion, or edit of a past record breaks the chain and is detectable via Verify. The chain is seeded on open from the last record already on disk, so it survives process restarts.

An autonomous cluster-mutator cannot rely on best-effort stdout logging: this is the durable, ordered, complete record of what it did and why.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Verify

func Verify(r io.Reader) error

Verify re-walks a chain and reports the first broken link, if any.

Types

type Auditor

type Auditor interface {
	Log(r Record) error
}

Auditor records action attempts. Implementations must be safe for concurrent use.

type Decision

type Decision string

Decision is the outcome of an action attempt.

const (
	DecisionExecuted Decision = "executed" // the op was applied to the cluster
	DecisionDryRun   Decision = "dry-run"  // auto dry-run: would have executed
	DecisionSkipped  Decision = "skipped"  // a safety gate withheld it (paused, low confidence, rate-limited…)
	DecisionDenied   Decision = "denied"   // outside the policy envelope
	DecisionFailed   Decision = "failed"   // execution was attempted and errored
)

Action-attempt outcomes.

type Logger

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

Logger is a file-backed, hash-chained Auditor.

func NewWriter

func NewWriter(w io.Writer) *Logger

NewWriter builds a Logger over an arbitrary writer (tests).

func Open

func Open(path string) (*Logger, error)

Open opens (creating if needed) an append-only audit log at path and seeds the hash chain from the last record already present.

func OpenVerified added in v0.3.0

func OpenVerified(path string) (*Logger, error)

OpenVerified opens the audit log like Open, but first re-walks the existing chain and refuses to open a chain whose integrity is broken (insertion, edit, or mid-chain deletion). An empty or absent file is a valid (zero-record) chain. Callers that must fail closed against an untrustworthy chain (executing action modes) should use this instead of Open; the mode-based fail/warn policy lives at the call site where the config is available.

It reads the file EXACTLY ONCE: the same scan that verifies the chain also yields the trusted seed hash, and that fd is reused as the append handle (seeked to end). This closes a TOCTOU window the previous implementation had — it verified, closed the fd, then re-read the tail via a second os.Open to seed the chaining hash, letting an attacker overwrite the tail in between so the Logger chained from a tampered base. Now the seed comes from the verified bytes and the handle is never reopened, so there is no verify→append gap.

func (*Logger) Close

func (l *Logger) Close() error

Close closes the underlying file, if any.

func (*Logger) Log

func (l *Logger) Log(r Record) error

Log appends a record, chaining it to the previous one. Safe for concurrent use.

type Nop

type Nop struct{}

Nop is an Auditor that drops records (local/no-audit fallback).

func (Nop) Log

func (Nop) Log(Record) error

Log implements Auditor.

type Record

type Record struct {
	Time     time.Time `json:"time"`
	Actor    string    `json:"actor"`            // "auto" | "approve:<user>" | "suggest"
	Op       string    `json:"op"`               // suspend | resume | reconcile | ""
	Target   string    `json:"target"`           // kind/namespace/name
	Decision Decision  `json:"decision"`         // executed | dry-run | skipped | denied | failed
	Reason   string    `json:"reason,omitempty"` // why skipped/denied/failed
	PrevHash string    `json:"prev_hash"`
	Hash     string    `json:"hash"`
}

Record is one audited action attempt. Hash and PrevHash are filled by Log.

Jump to

Keyboard shortcuts

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