audit

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package audit records an append-only actor/action/target trail through a pluggable Sink, with a Bun-backed sink and a Fiber helper that prefills request context.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Migrate

func Migrate(ctx context.Context, db *bun.DB) error

Migrate creates the audit_log table (if absent) and an index on (actor, created_at).

Types

type Entry

type Entry struct {
	bun.BaseModel `bun:"table:audit_log,alias:al"`

	ID        int64          `bun:"id,pk,autoincrement"`
	Actor     string         `bun:"actor"`
	Action    string         `bun:"action,notnull"`
	Target    string         `bun:"target"`
	TargetID  string         `bun:"target_id"`
	Metadata  map[string]any `bun:"metadata"`
	IP        string         `bun:"ip"`
	RequestID string         `bun:"request_id"`
	CreatedAt time.Time      `bun:"created_at,notnull"`
}

Entry is one audit record.

func List

func List(ctx context.Context, db *bun.DB, f Filter) ([]Entry, error)

List returns entries matching f, newest first.

type Filter

type Filter struct {
	Actor  string
	Action string
	Target string
	Limit  int
}

Filter narrows a List query; empty fields are ignored.

type Option

type Option func(*Recorder)

Option configures a Recorder.

func WithActor

func WithActor(fn func(*fiber.Ctx) string) Option

WithActor sets how the actor is derived from a request (e.g. auth.Subject).

type Recorder

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

Recorder records entries through a Sink.

func New

func New(sink Sink, opts ...Option) *Recorder

New returns a Recorder writing to sink.

func (*Recorder) FromRequest

func (r *Recorder) FromRequest(c *fiber.Ctx) Entry

FromRequest returns an Entry prefilled with Actor (via the configured extractor, if any), IP, and RequestID. The caller fills Action/Target/etc and passes it to Record.

func (*Recorder) Record

func (r *Recorder) Record(ctx context.Context, e Entry) error

Record sets CreatedAt (when zero) and writes the entry to the sink.

Example

Record an audit entry and read it back.

package main

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/uptrace/bun"
	"github.com/uptrace/bun/dialect/sqlitedialect"
	"github.com/uptrace/bun/driver/sqliteshim"

	"github.com/rahmadafandi/fibr/audit"
)

func main() {
	sqldb, _ := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
	db := bun.NewDB(sqldb, sqlitedialect.New())
	defer db.Close()
	ctx := context.Background()
	_ = audit.Migrate(ctx, db)

	rec := audit.New(audit.NewBunSink(db))
	_ = rec.Record(ctx, audit.Entry{
		Actor:    "admin",
		Action:   "user.suspend",
		Target:   "user",
		TargetID: "99",
	})

	entries, _ := audit.List(ctx, db, audit.Filter{Actor: "admin"})
	fmt.Println(entries[0].Action, entries[0].TargetID)
}
Output:
user.suspend 99

type Sink

type Sink interface {
	Record(ctx context.Context, e *Entry) error
}

Sink persists audit entries.

func NewBunSink

func NewBunSink(db *bun.DB) Sink

NewBunSink returns a Sink that inserts entries into db.

Jump to

Keyboard shortcuts

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