Documentation
¶
Overview ¶
Package auditwiring assembles the layer that hangs off the audit log.
The audit store is not read only by audit: an asset's provenance resolves its sources out of it (#1320), and the call catalog is written from the events passing through it (#1321). All three are one assembly — the store, the writer the configured delivery mode selects, the catalog decorator between them, and the capturer that reads back through the writer's flush barrier — and the order they are composed in is load-bearing. Composing them here keeps that order in one place, and keeps the platform facade from growing a third copy of it.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AsFlusher ¶
func AsFlusher(logger middleware.AuditLogger) provenance.Flusher
AsFlusher returns the audit logger as a provenance flush barrier when it buffers writes, and nil when it does not: a synchronous writer has nothing to wait for, and neither has a logger a deployment injected itself.
func NewLogger ¶
func NewLogger(store audit.Logger, syncDelivery bool, m *observability.Metrics) middleware.AuditLogger
NewLogger wraps an audit store in the writer the delivery mode selects and adapts it to the middleware's logger interface (#898).
Async (default): a bounded writer with a single drain goroutine, a per-write timeout, and drain-on-shutdown replaces the middleware's old per-call detached goroutine, which grew without bound under a stalled store (#884); a sustained outage sheds events. Sync: write on the request goroutine with a per-write timeout. Either way the adapter owns the writer; for async it drains the writer on Close through the platform's existing audit-logger Closer path, so no extra field is held anywhere.
func ProvenQueries ¶
func ProvenQueries(calls *callrecord.PostgresStore) middleware.ProvenQueryLister
ProvenQueries adapts the call catalog to the enrichment middleware's lister: the caller's own recorded queries that already answered something on a dataset, which is what a describe of that table carries beside the catalog's own context (#1321).
A nil catalog yields a nil lister rather than one that answers nothing, so a deployment without a database appends no such block at all.
Types ¶
type Config ¶
type Config struct {
// DB is the database the audit log and the call catalog live in.
DB *sql.DB
// RetentionDays bounds how long audit rows are kept.
RetentionDays int
// SyncDelivery writes each event on the request goroutine instead of
// through the bounded async writer, trading tool-call latency for
// backpressure and zero queue-overflow drops (#898).
SyncDelivery bool
// Metrics receives the writer's counters. Optional.
Metrics *observability.Metrics
// BuildURN names the dataset a table reference belongs to, so a
// cataloged query records the entities it read. Optional: without it a
// record still carries its statement, purpose and outcome.
BuildURN callrecord.URNBuilder
// CallRetentionDays bounds how long a recorded call that came to nothing
// is kept. Zero takes the catalog's default; a record something was built
// from, promoted, declined, or re-run is never swept.
CallRetentionDays int
// CallExcludePersonas names the personas whose calls are machinery rather
// than material a later session would re-run: their calls are audited and
// not cataloged, and the rows they wrote before the deployment declared
// them are swept whatever their age (#1614). Empty catalogs everything,
// which is what a deployment that configures nothing gets.
CallExcludePersonas []string
// Toolkits is the live toolkit registry, which a capture asks what request
// an api call addressed by an operation id made: the id and the values the
// caller passed are in the audit row, the path template they went into is
// in the connection's catalog (#1423). Optional.
Toolkits provenance.ToolkitLister
}
Config is what the assembly needs from the deployment.
type Layer ¶
type Layer struct {
// contains filtered or unexported fields
}
Layer is the assembled audit layer. Every member is reached through a nil-safe accessor: a deployment with audit disabled, and a platform built for a test that never assembled one, both answer "nothing here" rather than panicking on a write path that legitimately runs either way.
func Assemble ¶
Assemble builds the audit layer over db and starts the store's retention cleanup.
The composition order is the point: the catalog decorator wraps the store *inside* the delivery writer, so cataloging a call happens on the writer's own goroutine and costs the call nothing; and the capturer is handed the finished logger as its flush barrier, so a capture waits for the calls still queued in that writer — the newest of which is usually the one that produced the asset being saved.
func Injected ¶
func Injected(logger middleware.AuditLogger) *Layer
Injected wraps a logger a deployment supplied itself. It has no store behind it, so nothing derived from the audit log is available: the caller owns the delivery guarantees and the storage.
func (*Layer) Calls ¶
func (l *Layer) Calls() *callrecord.PostgresStore
Calls is the catalog of data-access calls derived from the log.
func (*Layer) Capturer ¶
func (l *Layer) Capturer() *provenance.Capturer
Capturer resolves the calls behind one asset write. Its Capture is nil-safe, so a write path may call it unconditionally.
func (*Layer) Close ¶
Close shuts the layer down in the order its assembly requires: the logger first, so a buffering writer drains its queue THROUGH the store, and only then the store and the sweepers that hold the same database handle. Closing the store first would strand every event still queued.
A close error never stops the sequence: each step is attempted and the errors are joined, because a stalled writer must not keep the store open.
func (*Layer) Logger ¶
func (l *Layer) Logger() middleware.AuditLogger
Logger is what the middleware writes audit events through.
func (*Layer) Recording ¶
Recording reports whether this deployment stores what its calls did.
It is the question callers actually have — whether to hand a call its own identifier, whether to record a resource read — and asking it here keeps them from reasoning about which member of the layer being nil implies it.
func (*Layer) Store ¶
func (l *Layer) Store() *auditpostgres.Store
Store is the audit log itself, read by the admin surfaces, the session read model and provenance capture. Nil when there is no database.