Documentation
¶
Overview ¶
Package audit provides structured security event logging for authentication and authorisation actions. It is designed for compliance requirements such as SOC 2, ISO 27001, and GDPR audit trails.
Quick start:
logger := audit.NewJSONLogger(os.Stdout)
logger.Log(ctx, audit.Event{
Type: audit.EventLogin,
Subject: "user-123",
Result: audit.ResultAllow,
IP: "1.2.3.4",
})
Middleware integration:
mux.Handle("/", audit.Middleware(logger)(handler))
Index ¶
- func Log(ctx context.Context, event Event) error
- func Middleware(l Logger, logRequests ...bool) func(http.Handler) http.Handler
- func WithLogger(ctx context.Context, l Logger) context.Context
- type Event
- type EventBuilder
- func (b *EventBuilder) Build() Event
- func (b *EventBuilder) Log(ctx context.Context) error
- func (b *EventBuilder) Logf(ctx context.Context) string
- func (b *EventBuilder) WithAction(action string) *EventBuilder
- func (b *EventBuilder) WithIP(ip string) *EventBuilder
- func (b *EventBuilder) WithMeta(key string, value any) *EventBuilder
- func (b *EventBuilder) WithRequestID(id string) *EventBuilder
- func (b *EventBuilder) WithResource(resource string) *EventBuilder
- type EventType
- type JSONLogger
- type Logger
- type MultiLogger
- type NOOPLogger
- type Result
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Middleware ¶
Middleware injects the logger into the request context and, optionally, logs every request automatically when logRequests is true. The logged event type is EventAccessGranted or EventAccessDenied based on the response status code (status ≥ 400 is treated as denied).
Usage — inject only (log manually inside handlers):
mux.Handle("/", audit.Middleware(logger)(handler))
Usage — auto-log every request:
mux.Handle("/", audit.Middleware(logger, true)(handler))
Types ¶
type Event ¶
type Event struct {
// ID is a unique identifier for this event (set automatically by JSONLogger
// if left empty — applications may set their own).
ID string `json:"id,omitempty"`
// Type classifies the event.
Type EventType `json:"type"`
// Timestamp is when the event occurred. Defaults to time.Now() when zero.
Timestamp time.Time `json:"timestamp"`
// Subject is the entity that performed the action (user ID, service name, etc.).
Subject string `json:"subject,omitempty"`
// Resource is the object that was acted upon (e.g. "posts/42", "users").
Resource string `json:"resource,omitempty"`
// Action is the operation that was attempted (e.g. "read", "delete").
Action string `json:"action,omitempty"`
// Result is the outcome of the event.
Result Result `json:"result,omitempty"`
// IP is the client IP address.
IP string `json:"ip,omitempty"`
// UserAgent is the client User-Agent string.
UserAgent string `json:"user_agent,omitempty"`
// RequestID correlates the event with an HTTP request trace.
RequestID string `json:"request_id,omitempty"`
// Meta holds arbitrary additional fields.
Meta map[string]any `json:"meta,omitempty"`
}
Event represents a single auditable security action.
type EventBuilder ¶
type EventBuilder struct {
// contains filtered or unexported fields
}
EventBuilder provides a fluent API for constructing Events.
func Eventf ¶
func Eventf(t EventType, subject string, result Result) *EventBuilder
Eventf is a convenience constructor for quickly building events.
audit.Eventf(audit.EventLogin, "user-123", audit.ResultAllow).WithIP("1.2.3.4")
func (*EventBuilder) Build ¶
func (b *EventBuilder) Build() Event
Build returns the constructed Event.
func (*EventBuilder) Log ¶
func (b *EventBuilder) Log(ctx context.Context) error
Log sends the event to the logger in ctx and returns any error.
func (*EventBuilder) Logf ¶
func (b *EventBuilder) Logf(ctx context.Context) string
Logf is a shorthand: build and log in one call, returning a formatted error string if logging fails (safe to ignore in non-critical paths).
func (*EventBuilder) WithAction ¶
func (b *EventBuilder) WithAction(action string) *EventBuilder
func (*EventBuilder) WithIP ¶
func (b *EventBuilder) WithIP(ip string) *EventBuilder
func (*EventBuilder) WithMeta ¶
func (b *EventBuilder) WithMeta(key string, value any) *EventBuilder
func (*EventBuilder) WithRequestID ¶
func (b *EventBuilder) WithRequestID(id string) *EventBuilder
func (*EventBuilder) WithResource ¶
func (b *EventBuilder) WithResource(resource string) *EventBuilder
type EventType ¶
type EventType string
EventType classifies a security-relevant action.
const ( // Authentication events. EventLogin EventType = "auth.login" EventLoginFailed EventType = "auth.login_failed" EventLogout EventType = "auth.logout" EventMFASuccess EventType = "auth.mfa_success" EventMFAFailed EventType = "auth.mfa_failed" // Token lifecycle. EventTokenIssued EventType = "token.issued" EventTokenVerified EventType = "token.verified" EventTokenRefreshed EventType = "token.refreshed" EventTokenRevoked EventType = "token.revoked" EventTokenExpired EventType = "token.expired" EventTokenInvalid EventType = "token.invalid" // API key lifecycle. EventAPIKeyIssued EventType = "apikey.issued" EventAPIKeyUsed EventType = "apikey.used" EventAPIKeyRevoked EventType = "apikey.revoked" EventAPIKeyInvalid EventType = "apikey.invalid" // Authorisation decisions. EventAccessGranted EventType = "authz.access_granted" EventAccessDenied EventType = "authz.access_denied" // Rate limiting. EventRateLimited EventType = "rate.limited" // Account management. EventPasswordChanged EventType = "account.password_changed" EventPasswordReset EventType = "account.password_reset" EventAccountLocked EventType = "account.locked" EventAccountUnlocked EventType = "account.unlocked" )
type JSONLogger ¶
type JSONLogger struct {
// contains filtered or unexported fields
}
JSONLogger writes newline-delimited JSON events to an io.Writer. Each event is a single JSON object terminated by a newline — compatible with log aggregators such as Loki, Datadog, CloudWatch, and Splunk.
func NewJSONLogger ¶
func NewJSONLogger(w io.Writer) *JSONLogger
NewJSONLogger creates a JSONLogger that writes to w.
type Logger ¶
Logger is the sink for audit events.
func FromContext ¶
FromContext retrieves the Logger from the context. Returns NOOPLogger when no logger is present, so callers never need to nil-check.
type MultiLogger ¶
type MultiLogger struct {
// contains filtered or unexported fields
}
MultiLogger fans out events to multiple loggers. All loggers are called even when one returns an error; the first error is returned.
func NewMultiLogger ¶
func NewMultiLogger(loggers ...Logger) *MultiLogger
NewMultiLogger creates a MultiLogger that writes to all provided loggers.
type NOOPLogger ¶
type NOOPLogger struct{}
NOOPLogger discards all events. Useful in tests or when audit logging is optional.