Versions in this module Expand all Collapse all v1 v1.0.0 Aug 25, 2026 Changes in this version + const APITokenPrefix + const ActionBootstrap + const ActionLockout + const ActionLogin + const ActionLogout + const ActionPasswordChange + const ActionPasswordReset + const ActionRoleChange + const ActionSessionRevoke + const ActionTOTP + const ActionTOTPConfirm + const ActionTOTPEnroll + const ActionThrottle + const ActionTokenCreate + const ActionTokenRevoke + const ActionUserCreate + const ActionUserDelete + const ActionUserDisable + const ActionUserEnable + const ActionUserList + const ArgonConcurrency + const ArgonWait + const BootstrapTokenBytes + const CookieName + const DefaultIPFailureThreshold + const DefaultIPThrottleDelay + const DefaultIdleTTL + const DefaultLockoutThreshold + const DefaultLockoutWindow + const DefaultSessionTTL + const MaxPasswordBytes + const MinPasswordChars + const RecoveryCodeCount + const TOTPDigits + const TOTPPeriod + const TOTPSkew + var AllPermissions = []Permission + var AllRoles = []Role + var ErrBootstrapClosed = errors.New("auth: bootstrap is closed: an owner already exists") + var ErrBusy = errors.New("auth: server busy, retry later") + var ErrForbidden = errors.New("auth: forbidden") + var ErrInvalidCredentials = errors.New("auth: invalid credentials") + var ErrInvalidEmail = errors.New("auth: invalid email address") + var ErrInvalidTOTP = errors.New("auth: invalid one-time code") + var ErrInvalidTokenName = errors.New("auth: token name must be 1-128 characters") + var ErrLastOwner = errors.New("auth: the last active owner cannot be demoted, disabled or deleted") + var ErrLockedOut = errors.New("auth: too many failed attempts, try again later") + var ErrMalformedHash = errors.New("auth: malformed password hash") + var ErrPasswordTooLong = fmt.Errorf("auth: password must be at most %d bytes", MaxPasswordBytes) + var ErrSelfTarget = errors.New("auth: you cannot do that to your own account") + var ErrSessionNotFound = errors.New("auth: session not found") + var ErrTOTPAlreadyEnabled = errors.New("auth: TOTP already enabled") + var ErrTOTPNotEnrolled = errors.New("auth: totp not enrolled") + var ErrTOTPNotPending = errors.New("auth: no pending TOTP enrollment") + var ErrTOTPRequired = fmt.Errorf("%w: second factor required", ErrUnauthenticated) + var ErrUnauthenticated = errors.New("auth: unauthenticated") + var ErrUserExists = errors.New("auth: a user with that email already exists") + var ErrUserNotFound = errors.New("auth: user not found") + var ErrWeakPassword = fmt.Errorf("auth: password must be at least %d characters", MinPasswordChars) + func GenerateRecoveryCodes(ctx context.Context, n int) (plain, hashes []string, err error) + func GenerateTOTP(issuer, account string) (secret, otpauthURL string, err error) + func HashPassword(ctx context.Context, pw string) (string, error) + func LoadOrCreateBootstrapToken(path string) (string, error) + func NeedsRehash(hash string) bool + func NormalizeEmail(email string) string + func TOTPCounter(t time.Time) int64 + func TOTPEnabled(u db.User) bool + func TokenEqual(a, b string) bool + func ValidateAPIToken(ctx context.Context, st *store.Store, plain string) (db.User, db.ApiToken, error) + func ValidateEmail(email string) (string, error) + func ValidateTOTP(secret, code string, now time.Time) bool + func ValidateTOTPCounter(secret, code string, now time.Time, lastUsed int64) (ok bool, counter int64) + func VerifyPassword(ctx context.Context, hash, pw string) (bool, error) + func VerifyRecoveryCode(ctx context.Context, hashes []string, code string) (index int, ok bool, err error) + type LoginResult struct + CookieValue string + NeedsTOTP bool + Session db.Session + User db.User + type Permission string + const PermAppsDeploy + const PermAppsManage + const PermAppsView + const PermAuditRead + const PermBilling + const PermDestructive + const PermLogsView + const PermSecretsWrite + const PermSettingsManage + const PermUsersManage + type Role string + const RoleAdmin + const RoleDeployer + const RoleOwner + const RoleViewer + func ParseRole(s string) (Role, error) + func (r Role) Can(p Permission) bool + func (r Role) String() string + func (r Role) Valid() bool + type Service struct + Audit audit.Sink + IPFailureThreshold int + IPThrottleDelay time.Duration + LockoutThreshold int + LockoutWindow time.Duration + Logger *slog.Logger + Now func() time.Time + Sessions *Sessions + Store *store.Store + TOTPSecret func(ctx context.Context, user db.User) (string, error) + func (s *Service) BootstrapOwner(ctx context.Context, presented, expected, email, password string) (db.User, error) + func (s *Service) ChangePassword(ctx context.Context, user db.User, ...) error + func (s *Service) ChangeRole(ctx context.Context, actor db.User, userID string, role Role) (db.User, error) + func (s *Service) CompleteTOTP(ctx context.Context, sessionID, code string) error + func (s *Service) ConfirmTOTP(ctx context.Context, user db.User, sessionID, code string) ([]string, error) + func (s *Service) CreateAPIToken(ctx context.Context, actor db.User, name string) (string, db.ApiToken, error) + func (s *Service) CreateUser(ctx context.Context, actor db.User, email, password string, role Role) (db.User, error) + func (s *Service) DeleteUser(ctx context.Context, actor db.User, userID string) error + func (s *Service) EnrollTOTP(ctx context.Context, user db.User, issuer string, ...) (TOTPEnrollment, error) + func (s *Service) GetUser(ctx context.Context, actor db.User, userID string) (db.User, error) + func (s *Service) ListSessions(ctx context.Context, actor db.User) ([]db.Session, error) + func (s *Service) ListUsers(ctx context.Context, actor db.User) ([]db.User, error) + func (s *Service) Login(ctx context.Context, email, password, ip, userAgent string) (LoginResult, error) + func (s *Service) Logout(ctx context.Context, sessionID string) error + func (s *Service) ResetPassword(ctx context.Context, actor db.User, userID, newPassword string) error + func (s *Service) RevokeAPIToken(ctx context.Context, actor db.User, tokenID string) error + func (s *Service) RevokeSession(ctx context.Context, actor db.User, sessionID string) error + func (s *Service) SetDisabled(ctx context.Context, actor db.User, userID string, disabled bool) (db.User, error) + func (s *Service) SweepLoginAttempts(ctx context.Context) (int64, error) + type Sessions struct + IdleTTL time.Duration + Now func() time.Time + Store *store.Store + TTL time.Duration + func (s *Sessions) ClearCookie() *http.Cookie + func (s *Sessions) Cookie(value string) *http.Cookie + func (s *Sessions) Create(ctx context.Context, userID, ip, userAgent string, totpVerified bool) (string, db.Session, error) + func (s *Sessions) Get(ctx context.Context, sessionID string) (db.Session, error) + func (s *Sessions) MarkTOTPVerified(ctx context.Context, sessionID string) error + func (s *Sessions) Revoke(ctx context.Context, sessionID string) error + func (s *Sessions) RevokeAll(ctx context.Context, userID string) error + func (s *Sessions) RevokeOthers(ctx context.Context, userID, keepSessionID string) error + func (s *Sessions) Validate(ctx context.Context, cookieValue string) (db.Session, db.User, error) + func (s *Sessions) ValidatePending(ctx context.Context, cookieValue string) (sess db.Session, user db.User, pending bool, err error) + type TOTPEnrollment struct + OTPAuthURL string + Secret string