audit

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: AGPL-3.0 Imports: 7 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:"
	// 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.

Jump to

Keyboard shortcuts

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