audit

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT, MIT Imports: 14 Imported by: 0

README

GoModularAuth Audit Plugin (gomodularauth-audit)

Structured, tamper-evident security audit logging for GoModularAuth. The Audit plugin functions as a zero-trust observational event consumer across GoModularAuth Core and all installed plugins (such as organizations, admin, api-keys, device-authorization, and authentication methods). It captures security-relevant actions into an immutable ledger while strictly sanitizing passwords, authentication tokens, OTP codes, and sensitive secrets.

Installation

go get github.com/BladiCreator/go-modular-auth/plugins/audit

Quick Start

package main

import (
	"context"
	"database/sql"
	"log"
	"time"

	auth "github.com/BladiCreator/go-modular-auth"
	audit "github.com/BladiCreator/go-modular-auth/plugins/audit"
	"github.com/BladiCreator/go-modular-auth/plugins/audit/plugins"
	adaptermem "github.com/BladiCreator/go-modular-auth/adapters/memory"
)

func main() {
	db, err := sql.Open("postgres", "postgres://user:pass@localhost:5432/auth_db?sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}

	auditModule := audit.New(
		// Optional: Buffer events asynchronously with 2 workers and batch size of 50
		audit.WithAsync(2, 1024, 50, 250*time.Millisecond),
	)

	appAuth, err := auth.New(auth.Config{
		Adapter: adaptermem.NewAdapter(),
		Plugins: []auth.PluginModule{auditModule},
	})
	if err != nil {
		log.Fatal(err)
	}

	// Retrieve typed Capability
	auditService, err := auth.Get[plugins.Audit](appAuth)
	if err != nil {
		log.Fatal(err)
	}

	// Query recent records
	records, err := auditService.QueryByActor(context.Background(), "user_12345", 20)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Found %d audit records", len(records))
}

Detailed guide: doc/plugins/audit.md.

Documentation

Overview

Package audit provides structured security audit logging capabilities (reserved module).

Index

Constants

View Source
const (
	EventAuditRecorded auth.EventName = "audit.record.created"
)

Event names emitted or tracked by the audit plugin.

View Source
const (
	ModelAuditRecords = "audit_records"
)
View Source
const PluginID = "audit"

PluginID identifies this plugin in the GoModularAuth runtime.

Variables

View Source
var (
	// ErrStoreRequired indicates that an AuditStore implementation was not supplied in configuration.
	ErrStoreRequired = errors.New("audit: audit store is required")

	// ErrEventRequired indicates an attempt to write an audit record with an empty event identifier.
	ErrEventRequired = errors.New("audit: event identifier cannot be empty")

	// ErrRecordNotFound indicates that the requested audit record does not exist in storage.
	ErrRecordNotFound = errors.New("audit: record not found")

	// ErrNilRecord indicates that an audit record pointer provided for persistence was nil.
	ErrNilRecord = errors.New("audit: record cannot be nil")

	// ErrInvalidFilter indicates invalid query or pagination criteria.
	ErrInvalidFilter = errors.New("audit: invalid filter criteria")
)

Sentinel errors returned by the audit plugin and store implementations.

Functions

func RegisterSchema

func RegisterSchema(s *schema.Schema) error

RegisterSchema registers the audit_records model in the compiled schema.

func SanitizeMetadata

func SanitizeMetadata(input any) map[string]any

SanitizeMetadata takes arbitrary metadata or payload and produces a scrubbed, safe map[string]any strictly free of plaintext secrets, tokens, OTPs and passwords.

Types

type Actor

type Actor struct {
	Subject   string             `json:"subject"`
	Type      auth.PrincipalType `json:"type"`
	IPAddress string             `json:"ip_address,omitempty"`
	UserAgent string             `json:"user_agent,omitempty"`
}

Actor encapsulates the security principal initiating or associated with the audited action.

type Audit

type Audit interface {
	// Record manually registers an explicit audit entry, ensuring sanitization before persistence.
	Record(ctx context.Context, record *AuditRecord) error

	// Query searches the audit log with customizable filtering and pagination criteria.
	Query(ctx context.Context, filter ListFilter) (*ListResult, error)

	// GetByID retrieves a single audit entry by its unique identifier.
	GetByID(ctx context.Context, id string) (*AuditRecord, error)

	// QueryByActor returns audit entries performed by or associated with a specific actor subject.
	QueryByActor(ctx context.Context, subject string, limit int) ([]*AuditRecord, error)

	// QueryByTarget returns audit entries affecting a specific target resource type and identifier.
	QueryByTarget(ctx context.Context, targetType, targetID string, limit int) ([]*AuditRecord, error)

	// QueryByOrganization returns paginated audit records scoped to a multi-tenant organization.
	QueryByOrganization(ctx context.Context, orgID string, filter ListFilter) (*ListResult, error)
}

Audit represents the strongly typed public capability provided by the audit plugin. Applications retrieve this capability via auth.Get[plugins.Audit]().

type AuditRecord

type AuditRecord struct {
	ID             string         `json:"id"`
	Timestamp      time.Time      `json:"timestamp"`
	Event          string         `json:"event"`
	Action         string         `json:"action"`
	ActorSubject   string         `json:"actor_subject"`
	ActorType      string         `json:"actor_type"`
	TargetType     string         `json:"target_type"`
	TargetID       string         `json:"target_id"`
	Outcome        Outcome        `json:"outcome"`
	OrganizationID string         `json:"organization_id,omitempty"`
	IPAddress      string         `json:"ip_address,omitempty"`
	UserAgent      string         `json:"user_agent,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
	ErrorMessage   string         `json:"error_message,omitempty"`
}

AuditRecord represents an immutable audit log entry capturing a security-relevant event.

func (*AuditRecord) Validate

func (r *AuditRecord) Validate() error

Validate ensures all mandatory audit record fields are populated and sets defaults.

type AuditRecordedPayload

type AuditRecordedPayload struct {
	RecordID  string    `json:"record_id"`
	Event     string    `json:"event"`
	Timestamp time.Time `json:"timestamp"`
}

AuditRecordedPayload describes an audit log creation event.

type Config

type Config struct {
	Filter        EventFilter
	AsyncWorkers  int
	BufferSize    int
	BatchSize     int
	FlushInterval time.Duration
	OrgResolver   OrgResolver
}

Config holds settings for the audit plugin.

type EventFilter

type EventFilter func(ev auth.Event) bool

EventFilter is a predicate function to decide if an event should be audited. Returns true to audit, false to drop.

type ListFilter

type ListFilter struct {
	ActorSubject   string    `json:"actor_subject,omitempty"`
	ActorType      string    `json:"actor_type,omitempty"`
	TargetType     string    `json:"target_type,omitempty"`
	TargetID       string    `json:"target_id,omitempty"`
	Event          string    `json:"event,omitempty"`
	Outcome        Outcome   `json:"outcome,omitempty"`
	OrganizationID string    `json:"organization_id,omitempty"`
	Since          time.Time `json:"since,omitempty"`
	Until          time.Time `json:"until,omitempty"`
	Limit          int       `json:"limit,omitempty"`
	Offset         int       `json:"offset,omitempty"`
}

ListFilter defines search and pagination parameters for querying audit records.

func (*ListFilter) Normalize

func (f *ListFilter) Normalize()

Normalize validates and applies reasonable defaults to filter parameters.

type ListResult

type ListResult struct {
	Records []*AuditRecord `json:"records"`
	Total   int            `json:"total"`
	Limit   int            `json:"limit"`
	Offset  int            `json:"offset"`
}

ListResult wraps the matching audit entries and total count for pagination.

type Module

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

Module implements auth.PluginModule for structured security auditing.

func New

func New(opts ...Option) *Module

New creates an installable audit PluginModule with functional options.

func (*Module) Close

func (m *Module) Close() error

Close flushes pending asynchronous records and closes background workers.

func (*Module) ID

func (m *Module) ID() string

ID returns the module's unique identifier.

func (*Module) Init

func (m *Module) Init(h *auth.Host) error

Init configures infrastructure, registers the typed Capability in GoModularAuth, and subscribes the audit consumer to all dispatched events.

func (*Module) RegisterSchema

func (m *Module) RegisterSchema(s *schema.Schema) error

RegisterSchema contributes the audit_records model to the compiled schema.

func (*Module) Start

func (m *Module) Start(ctx context.Context) error

Start implements auth.Lifecycle.

func (*Module) Stop

func (m *Module) Stop(ctx context.Context) error

Stop implements auth.Lifecycle by flushing pending asynchronous records and closing background workers.

type Option

type Option func(*Config)

Option configures audit plugin behavior.

func WithAsync

func WithAsync(workers, bufferSize, batchSize int, flushInterval time.Duration) Option

WithAsync enables asynchronous background worker processing for non-blocking audit logging.

func WithFilter

func WithFilter(f EventFilter) Option

WithFilter configures a predicate to selectively filter out events from being audited.

func WithOrgResolver

func WithOrgResolver(resolver OrgResolver) Option

WithOrgResolver configures a custom organization ID extractor for tenant scoping.

type OrgResolver

type OrgResolver func(ctx context.Context, ev auth.Event) string

OrgResolver extracts an organization ID from context or event payload.

type Outcome

type Outcome string

Outcome classifies the result of an audited operation.

const (
	// OutcomeSuccess denotes an operation that completed successfully.
	OutcomeSuccess Outcome = "success"
	// OutcomeFailure denotes an operation that failed, was rejected, or unauthorized.
	OutcomeFailure Outcome = "failure"
	// OutcomeUnknown denotes an operation whose explicit result was indeterminate.
	OutcomeUnknown Outcome = "unknown"
)

type TargetResource

type TargetResource struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

TargetResource specifies the subject or resource affected by an audited event.

Directories

Path Synopsis
Package migrations contains SQL schema migrations for the audit plugin.
Package migrations contains SQL schema migrations for the audit plugin.
Package plugins exposes capability aliases for GoModularAuth plugins.
Package plugins exposes capability aliases for GoModularAuth plugins.

Jump to

Keyboard shortcuts

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