resourceaudit

package
v1.126.6 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package resourceaudit records what happens to a managed resource as audit events: reads of its content, which also stamp the durable last-read time on the resource row, and the move that refiles it in another library.

It exists so the doors that serve a resource's bytes — MCP resources/read, a search `fetch` of an mcp:resource:<id> reference, the REST content download, and the portal's own preview of an image in the library — produce one event shape from one implementation. A per-surface copy would drift on exactly the fields a curator asks about ("which door was this read through, and when was it last touched"), and the usage rollup reads those fields back by name.

The recorder is the audit-enabled switch for the feature: a deployment with audit disabled wires no recorder, so reads are neither audited nor counted and continue to serve unchanged. Recording never fails a read — a resource whose audit row cannot be written is still a resource the caller asked for.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Recorder

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

Recorder writes resource read events through an audit logger and stamps the resource's last-read column.

func New

func New(logger middleware.AuditLogger, tracker resource.ReadTracker) *Recorder

New builds a recorder over an audit logger and an optional read tracker.

logger determines the delivery discipline: pass the platform's async logger on the MCP paths, where a synchronous insert would sit in front of an agent's read, and the store-backed logger on the REST path, where the caller is a human clicking Download. A nil logger yields a nil Recorder, which every call site tolerates, so "audit disabled" needs no second switch.

tracker may be nil (a store that does not implement resource.ReadTracker); the events are still written and only the sortable last-read column goes unstamped.

func (*Recorder) RecordMove added in v1.126.3

func (r *Recorder) RecordMove(ctx context.Context, ev resource.MoveEvent)

RecordMove writes one resource_move audit event. A folder rename produces one per resource it carried, which is what makes the trail answer "what address does this file have now" for each of them rather than only for the folder.

A failure is logged and swallowed: the resource has already been refiled, and a lost audit row must not become a failed move reported to somebody whose file did move.

It shares the Recorder with reads because it shares everything that decides how the row is written -- the logger, the identity overlay, the delivery discipline -- and because "what has happened to this resource" is one trail.

func (*Recorder) RecordRead

func (r *Recorder) RecordRead(ctx context.Context, ev resource.ReadEvent)

RecordRead writes one resource_read audit event and, for every surface but the portal's preview, stamps the resource's last-read time. Both failures are logged and swallowed: the content has already been served (or is about to be), and a lost audit row must not become a failed read.

The stamp is a single UPDATE by primary key issued inline rather than from a goroutine: a detached write per read is the unbounded-goroutine shape a stalled database turns into a leak (#884), and the audit write itself is already where the latency budget went.

Jump to

Keyboard shortcuts

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