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" // EventUserTokenReuse is emitted when an already-revoked refresh token // is presented before its expiry. That is evidence a token leaked, so // every session for the principal is revoked in response. Route this // one somewhere a human sees it. EventUserTokenReuse EventType = "user.token.reuse_detected" 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" // EventUserUnlocked is an operator lifting an account's lockout. EventUserUnlocked EventType = "user.unlocked" // EventAccountLinked and EventAccountUnlinked record an external // identity being attached to or detached from a user. Linking is a // credential grant -- afterwards, that provider can sign this account // in -- so it belongs in the same trail as a password change. // Passkey events. A registration is a credential grant -- afterwards // that authenticator can sign this account in -- and a clone warning // is the specification's one built-in signal that a private key has // been copied, so both belong in the same trail as a password change. EventPasskeyRegistered EventType = "user.passkey.registered" EventPasskeyRemoved EventType = "user.passkey.removed" EventPasskeyLogin EventType = "user.passkey.login" EventPasskeyCloneWarning EventType = "user.passkey.clone_warning" // Passwordless email sign-in. EventEmailLoginExhausted means a code // was destroyed by too many wrong guesses, which is an attack in // progress far more often than it is a typo. EventEmailLoginRequested EventType = "user.email_login.requested" EventEmailLoginSucceeded EventType = "user.email_login.succeeded" EventEmailLoginExhausted EventType = "user.email_login.exhausted" EventAccountLinked EventType = "user.account.linked" EventAccountUnlinked EventType = "user.account.unlinked" 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" // EventSuperuserTokenReuse is the operator-plane counterpart of // EventUserTokenReuse. EventSuperuserTokenReuse EventType = "superuser.token.reuse_detected" EventSuperuserDeactivated EventType = "superuser.deactivated" EventSuperuserImpersonated EventType = "superuser.impersonated" // An operator's own account: the verbs a signed-in operator runs on // itself, each as security-relevant as a sign-in. EventSuperuserPasswordChanged EventType = "superuser.password.changed" EventSuperuserTwoFactorEnabled EventType = "superuser.twofactor.enabled" EventSuperuserTwoFactorDisabled EventType = "superuser.twofactor.disabled" EventSuperuserBackupCodesRegenerated EventType = "superuser.twofactor.backup_codes_regenerated" EventSuperuserSessionRevoked EventType = "superuser.session.revoked" 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 ¶
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.
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().