audit

package
v0.30.5 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package audit provides audit event storage and streaming functionality.

Index

Constants

View Source
const (
	OutcomeSuccess = "success"
	OutcomeFailure = "failure"
)

Outcomes of an event.

View Source
const MaxUserAgent = 512

MaxUserAgent bounds the User-Agent an emitter records.

Variables

This section is empty.

Functions

func RequestID

func RequestID(ctx context.Context) string

RequestID returns the ID chi's request-ID middleware gave the request ctx belongs to, or "" outside such a request.

func SanitizeUserAgent

func SanitizeUserAgent(ua string) string

SanitizeUserAgent returns the User-Agent an emitter may record: the client sends it, so it can carry anything. Control characters and invalid UTF-8 are removed; a value that then looks like it holds an email address or a credential is dropped (""), and any other is cut to MaxUserAgent bytes.

The value is cleaned before it is checked, so control characters cannot split an address or a token past the check. The check is a heuristic: it catches the common shapes, not every possible piece of personal data or a short secret.

Types

type Actor

type Actor struct {
	ID         uuid.UUID `json:"id"`
	Type       string    `json:"type"` // "human" | "application" | "agent" | "service"
	Identifier string    `json:"identifier"`
}

Actor represents the actor in an audit event.

type Context

type Context struct {
	TenantID  *uuid.UUID `json:"tenant_id,omitempty"`
	SessionID string     `json:"session_id,omitempty"`
	ClientIP  string     `json:"client_ip,omitempty"`
	UserAgent string     `json:"user_agent,omitempty"`
	// RequestID is the ID of the HTTP request that caused the event, as
	// the router's request-ID middleware assigned it.
	RequestID string `json:"request_id,omitempty"`
}

Context represents the context of an audit event.

type Emitter

type Emitter interface {
	// Emit records an audit event.
	Emit(ctx context.Context, event *Event) error
}

Emitter defines the interface for emitting audit events.

type Event

type Event struct {
	ID        uuid.UUID      `json:"id"`
	Sequence  int64          `json:"sequence"`
	Timestamp time.Time      `json:"timestamp"`
	EventType string         `json:"event_type"`
	Action    string         `json:"action"`
	Actor     Actor          `json:"actor"`
	Resource  Resource       `json:"resource"`
	Context   Context        `json:"context"`
	Outcome   string         `json:"outcome"` // "success" | "failure"
	Details   map[string]any `json:"details,omitempty"`
}

Event represents a standardized audit event.

type LogEmitter

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

LogEmitter writes every event as one structured log record, a security event log for deployments without an audit store. Failures are logged at warning level, successes at info.

func NewLogEmitter

func NewLogEmitter(logger *slog.Logger) *LogEmitter

NewLogEmitter returns a LogEmitter writing to logger, or to slog.Default when logger is nil.

func (*LogEmitter) Emit

func (e *LogEmitter) Emit(ctx context.Context, ev *Event) error

Emit logs ev under the message "security event".

type MemoryStore

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

MemoryStore is an in-memory implementation of the audit Store interface. This is suitable for development and testing but should not be used in production.

func NewMemoryStore

func NewMemoryStore(maxEvents int) *MemoryStore

NewMemoryStore creates a new in-memory audit store.

func (*MemoryStore) Acknowledge

func (s *MemoryStore) Acknowledge(ctx context.Context, sequence int64) error

Acknowledge marks events up to a sequence as acknowledged.

func (*MemoryStore) GetByActor

func (s *MemoryStore) GetByActor(ctx context.Context, actorID uuid.UUID, limit int) ([]*Event, error)

GetByActor retrieves events for a specific actor.

func (*MemoryStore) GetByResource

func (s *MemoryStore) GetByResource(ctx context.Context, resourceType string, resourceID uuid.UUID, limit int) ([]*Event, error)

GetByResource retrieves events for a specific resource.

func (*MemoryStore) GetBySequence

func (s *MemoryStore) GetBySequence(ctx context.Context, fromSequence int64, limit int) ([]*Event, error)

GetBySequence retrieves events starting from a sequence number.

func (*MemoryStore) GetByTimeRange

func (s *MemoryStore) GetByTimeRange(ctx context.Context, from, to time.Time, limit int) ([]*Event, error)

GetByTimeRange retrieves events within a time range.

func (*MemoryStore) GetLastAcknowledged

func (s *MemoryStore) GetLastAcknowledged(ctx context.Context) (int64, error)

GetLastAcknowledged returns the last acknowledged sequence number.

func (*MemoryStore) GetLastSequence

func (s *MemoryStore) GetLastSequence(ctx context.Context) (int64, error)

GetLastSequence returns the last recorded sequence number.

func (*MemoryStore) Record

func (s *MemoryStore) Record(ctx context.Context, event *Event) (int64, error)

Record stores an audit event and returns its sequence number.

type MultiEmitter

type MultiEmitter []Emitter

MultiEmitter hands every event to each of its emitters in order, for a deployment that records security events in more than one place, such as a log (LogEmitter) and a file of OCSF events (package ocsfaudit).

func NewMultiEmitter

func NewMultiEmitter(emitters ...Emitter) MultiEmitter

NewMultiEmitter returns a MultiEmitter of the non-nil emitters.

func (MultiEmitter) Emit

func (m MultiEmitter) Emit(ctx context.Context, ev *Event) error

Emit hands ev to every emitter, also after one of them fails, and returns their errors joined.

type NopEmitter

type NopEmitter struct{}

NopEmitter discards every event. It is the default where an emitter is optional.

func (NopEmitter) Emit

Emit discards ev.

type Resource

type Resource struct {
	Type       string    `json:"type"`
	ID         uuid.UUID `json:"id"`
	Identifier string    `json:"identifier,omitempty"`
}

Resource represents the resource in an audit event.

type Store

type Store interface {
	// Record stores an audit event and returns its sequence number.
	Record(ctx context.Context, event *Event) (int64, error)

	// GetBySequence retrieves events starting from a sequence number.
	GetBySequence(ctx context.Context, fromSequence int64, limit int) ([]*Event, error)

	// GetByTimeRange retrieves events within a time range.
	GetByTimeRange(ctx context.Context, from, to time.Time, limit int) ([]*Event, error)

	// GetByActor retrieves events for a specific actor.
	GetByActor(ctx context.Context, actorID uuid.UUID, limit int) ([]*Event, error)

	// GetByResource retrieves events for a specific resource.
	GetByResource(ctx context.Context, resourceType string, resourceID uuid.UUID, limit int) ([]*Event, error)

	// GetLastSequence returns the last recorded sequence number.
	GetLastSequence(ctx context.Context) (int64, error)

	// Acknowledge marks events up to a sequence as acknowledged.
	Acknowledge(ctx context.Context, sequence int64) error

	// GetLastAcknowledged returns the last acknowledged sequence number.
	GetLastAcknowledged(ctx context.Context) (int64, error)
}

Store defines the interface for audit event storage.

type StreamConfig

type StreamConfig struct {
	Enabled         bool
	Endpoint        string
	BearerToken     string // #nosec G117 - This is configuration, not a hardcoded secret
	BatchSize       int
	FlushIntervalMs int
}

StreamConfig holds configuration for audit streaming.

Directories

Path Synopsis
Package ocsfaudit writes SystemForge's security events as OCSF (Open Cybersecurity Schema Framework) events, one JSON object per line, for a security data lake or SIEM that ingests OCSF.
Package ocsfaudit writes SystemForge's security events as OCSF (Open Cybersecurity Schema Framework) events, one JSON object per line, for a security data lake or SIEM that ingests OCSF.

Jump to

Keyboard shortcuts

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