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

audit

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package audit owns the durable trail of admin mutations: the record, the actor vocabulary, and the retention window. Key creation, credential changes, and policy edits each leave one actor-attributed record here, so "who changed this and when" outlives the request that did it.

A record never holds a credential value. It names the subject a mutation touched — a key ID, a provider, a preset name — and how the attempt ended, and nothing the store would have to protect.

Index

Constants

View Source
const (
	// ActorKeyPrefix marks an actor authenticated by a gateway API key. The
	// suffix is the key's name, or its ID when the key has no name.
	ActorKeyPrefix = "key:"
	// ActorConsolePrefix marks a machine-local console session. The suffix is
	// the grant kind that minted it.
	ActorConsolePrefix = "console:"
	// ActorUserPrefix marks an identity-provider user. The suffix is the
	// subject the provider asserted.
	ActorUserPrefix = "user:"
	// ActorOperatorPrefix marks a command that an operator ran on a host.
	// The suffix is the operating system user that ran it.
	ActorOperatorPrefix = "operator:"
	// ActorAnonymous names a request that carried no identity at all, which
	// only a deployment with authentication disabled produces.
	ActorAnonymous = "anonymous"
)

Actor prefixes. An actor is one string with a kind prefix, so the trail reads without a join: "key:ci-deployer", "console:local-token", "user:auth0|5f7c…".

View Source
const (
	// OutcomeOK reports the mutation succeeded.
	OutcomeOK = "ok"
	// OutcomeError reports the store refused or failed the mutation.
	OutcomeError = "error"
)

Outcomes. A record lands only when a mutation reached its store, so the outcome separates the write that took from the write the store refused.

View Source
const (
	// DefaultRetention bounds how far back the trail reaches: 400 days, past
	// an annual compliance review with margin for the review to run late.
	DefaultRetention = 400 * 24 * time.Hour
	// MaxListLimit caps one page. It matches the usage listing's cap, so
	// every admin listing honors the same ceiling.
	MaxListLimit = 1000
)

Variables

View Source
var ErrInvalidQuery = errors.New("invalid audit query")

ErrInvalidQuery reports a query the repository refuses to run: a bad cursor or a limit outside its bounds.

View Source
var ErrStoreRequired = errors.New("audit storage is required")

ErrStoreRequired reports a missing relational store.

Functions

This section is empty.

Types

type Page

type Page struct {
	Records []Record
	// NextCursor resumes the walk, or is empty on the last page.
	NextCursor string
}

Page is one bounded read of the trail, newest first.

type Query

type Query struct {
	// Action keeps only records with this exact action.
	Action string
	// Actor keeps only records with this exact actor.
	Actor string
	// Since and Until bound the time window, inclusive of Since and
	// exclusive of Until.
	Since time.Time
	Until time.Time
	// Limit caps the page, defaulting to defaultListLimit and refusing
	// values above MaxListLimit.
	Limit int
	// Cursor resumes a walk from a previous page's NextCursor.
	Cursor string
}

Query filters one page of the trail. Zero values place no filter.

type Record

type Record struct {
	// ID orders records and carries the paging cursor. The store assigns it;
	// a caller-provided value is ignored.
	ID int64 `json:"id"`
	// Time is when the mutation happened, in UTC.
	Time time.Time `json:"time"`
	// Actor is who asked, with its kind prefix.
	Actor string `json:"actor"`
	// Action names the mutation, as concept.verb: "key.create",
	// "auth_mode.update".
	Action string `json:"action"`
	// Subject is the identifier the mutation touched. Never a credential
	// value.
	Subject string `json:"subject"`
	// Outcome is OutcomeOK or OutcomeError.
	Outcome string `json:"outcome"`
	// RequestID is the gateway request that carried the mutation, so the
	// trail joins the usage listing and the request log. It is empty for a
	// write that reached the store without a request context.
	RequestID string `json:"request_id"`
}

Record is one admin mutation: when, who, what they did, what it touched, and how it ended.

type Repository

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

Repository is the sqlstore-backed trail. It writes one row per mutation and prunes rows past the retention window on each write.

func Open

func Open(db *sqlstore.DB, retention time.Duration) (*Repository, error)

Open returns a repository over an already-migrated store. A retention at or below zero selects the default window.

func (*Repository) List

func (r *Repository) List(ctx context.Context, query Query) (Page, error)

List returns one page of the trail, newest first, honoring the query's filters and cursor.

func (*Repository) Record

func (r *Repository) Record(ctx context.Context, record Record) error

Record appends one audit record and prunes entries past the retention window. A zero time takes the clock's now.

func (*Repository) RecordTx added in v1.3.0

func (r *Repository) RecordTx(ctx context.Context, tx *sql.Tx, record Record) error

RecordTx appends one audit record inside the caller transaction. The record commits or rolls back with the mutation it describes. It prunes like Record.

Jump to

Keyboard shortcuts

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