audit

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package audit lets a host observe authit's security-relevant events — logins, lockouts, password and 2FA changes, session and token revocation, impersonation — without authit dictating where they end up.

It is entirely opt-in: every service's Config carries an AuditLogger field, and leaving it nil means events are simply not recorded — the same nil-safe shape as user.Config's EmailSender or team.Config's Admission. A host that needs a compliance trail (SOC2, GDPR, PCI-DSS) implements Logger against its own log pipeline or SIEM; SlogLogger covers the common case of just wanting these events in application logs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

type Event struct {
	Type   EventType
	Result Result

	// ActorID identifies who performed the action — a user, superuser, or
	// team member id, depending on Type. Empty when no principal is known
	// yet, e.g. a failed login against an email with no matching account.
	ActorID string
	// TargetID identifies what the action was performed on, when that
	// differs from ActorID — the deactivated superuser, the removed team
	// member, the impersonated user, the revoked token.
	TargetID string
	// Email identifies the acting or targeted principal by address, for
	// events where no id is available yet (registration, a failed login
	// before the account is known) or where the address is the natural
	// key (an invitation).
	Email string

	UserAgent string
	IPAddress string

	// Metadata carries event-specific detail — a team id and new role for
	// EventTeamMemberRoleChanged, a token name for EventPATCreated —
	// without growing Event's fixed shape for every plane's particulars.
	Metadata map[string]any
}

Event is one audit record.

type EventType

type EventType string

EventType identifies what happened.

const (
	EventUserRegistered        EventType = "user.registered"
	EventUserLoginSucceeded    EventType = "user.login.succeeded"
	EventUserLoginFailed       EventType = "user.login.failed"
	EventUserLoginLocked       EventType = "user.login.locked"
	EventUserLogout            EventType = "user.logout"
	EventUserTokenRefreshed    EventType = "user.token.refreshed"
	EventUserSessionRevoked    EventType = "user.session.revoked"
	EventUserPasswordChanged   EventType = "user.password.changed"
	EventUserPasswordReset     EventType = "user.password.reset"
	EventUserEmailVerified     EventType = "user.email.verified"
	EventUserTwoFactorEnabled  EventType = "user.twofactor.enabled"
	EventUserTwoFactorDisabled EventType = "user.twofactor.disabled"

	EventSuperuserCreated        EventType = "superuser.created"
	EventSuperuserLoginSucceeded EventType = "superuser.login.succeeded"
	EventSuperuserLoginFailed    EventType = "superuser.login.failed"
	EventSuperuserLoginLocked    EventType = "superuser.login.locked"
	EventSuperuserLogout         EventType = "superuser.logout"
	EventSuperuserTokenRefreshed EventType = "superuser.token.refreshed"
	EventSuperuserDeactivated    EventType = "superuser.deactivated"
	EventSuperuserImpersonated   EventType = "superuser.impersonated"

	EventTeamCreated             EventType = "team.created"
	EventTeamMemberRoleChanged   EventType = "team.member.role_changed"
	EventTeamMemberStatusChanged EventType = "team.member.status_changed"
	EventTeamMemberRemoved       EventType = "team.member.removed"
	EventTeamInvitationCreated   EventType = "team.invitation.created"
	EventTeamInvitationAccepted  EventType = "team.invitation.accepted"
	EventTeamInvitationRevoked   EventType = "team.invitation.revoked"

	EventPATCreated EventType = "pat.created"
	EventPATRevoked EventType = "pat.revoked"

	EventDeviceApproved EventType = "device.approved"
	EventDeviceDenied   EventType = "device.denied"
)

type Logger

type Logger interface {
	Log(ctx context.Context, event Event)
}

Logger receives audit events. Implementations must be safe for concurrent use — every service method that emits an event may be called from a different goroutine.

Log takes no error return: a host that needs delivery guarantees (retry, buffering, an outbox) owns that inside its implementation. authit itself never lets a logging failure affect the outcome of the operation being audited — Log is called after the fact, best-effort.

type NoopLogger

type NoopLogger struct{}

NoopLogger discards every event. It is the default a service falls back to when its Config leaves AuditLogger nil.

func (NoopLogger) Log

Log implements Logger by doing nothing.

type Result

type Result string

Result is the outcome of the event.

const (
	ResultSuccess Result = "success"
	ResultFailure Result = "failure"
	ResultDenied  Result = "denied"
)

type SlogLogger

type SlogLogger struct {
	// Logger receives every event. Nil uses slog.Default().
	Logger *slog.Logger
}

SlogLogger adapts a *slog.Logger to Logger, for the common case of wanting audit events in application logs rather than a dedicated system. The zero value logs to slog.Default().

func (SlogLogger) Log

func (l SlogLogger) Log(ctx context.Context, event Event)

Log implements Logger. Events whose Result is ResultFailure or ResultDenied log at Warn; everything else logs at Info.

Jump to

Keyboard shortcuts

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