auth

package
v0.0.0-...-592c247 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidCredentials reports a username or password mismatch.
	ErrInvalidCredentials = errors.New("invalid credentials")
	// ErrUserNotFound reports a missing local user record.
	ErrUserNotFound = errors.New("user not found")
	// ErrUserAlreadyExists reports a duplicate local username.
	ErrUserAlreadyExists = errors.New("user already exists")
	// ErrLastAdminRequired reports an operation that would remove the last admin.
	ErrLastAdminRequired = errors.New("last admin must remain an admin")
	// ErrSessionNotFound reports a missing or revoked session identifier.
	ErrSessionNotFound = errors.New("session not found")
	// ErrTotpRequired reports a missing second factor for a TOTP-enabled account.
	ErrTotpRequired = errors.New("totp code required")
	// ErrInvalidTotpCode reports a second factor mismatch.
	ErrInvalidTotpCode = errors.New("invalid totp code")
	// ErrTotpSetupNotFound reports a missing or expired pending TOTP setup.
	ErrTotpSetupNotFound = errors.New("totp setup not found")
	// ErrPasswordTooWeak reports a password that is shorter than the
	// minimum length, empty, or exceeds the length cap.
	ErrPasswordTooWeak = errors.New("password must be between 6 and 1024 characters")
	// ErrSessionStoreUnavailable reports that the persistent session store
	// rejected a write during login. P2-SEC-07: the in-memory session alone
	// is not acceptable — it would silently disappear on the next control-
	// plane restart. The handler surfaces this as 503 so the caller retries.
	ErrSessionStoreUnavailable = errors.New("session store unavailable")
)

Functions

This section is empty.

Types

type BootstrapInput

type BootstrapInput struct {
	Username string
	Password string
	Role     Role
}

BootstrapInput describes the initial user record to create.

type LoginInput

type LoginInput struct {
	Username string
	Password string
	TotpCode string
	// PriorSessionID, if non-empty, identifies a pre-authentication session
	// cookie that the browser carried into the login request. On successful
	// authentication the service invalidates this ID in both the in-memory map
	// and the persistent session store before issuing a fresh session. This
	// defeats session fixation (an attacker who planted a cookie pre-login
	// cannot continue to use that ID after the victim authenticates).
	PriorSessionID string
}

LoginInput describes the operator credentials submitted during login.

type Role

type Role string

Role identifies the RBAC role assigned to a local operator account.

const (
	// RoleViewer can inspect fleet state but cannot mutate it.
	RoleViewer Role = "viewer"
	// RoleOperator can execute control-plane commands.
	RoleOperator Role = "operator"
	// RoleAdmin can manage security-sensitive settings.
	RoleAdmin Role = "admin"
)

type Service

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

Service provides local-account hashing, TOTP, and session issuance.

func NewService

func NewService() *Service

NewService constructs an in-memory local-auth service.

func NewServiceWithStore

func NewServiceWithStore(userStore storage.UserStore) *Service

NewServiceWithStore constructs an auth service that persists users through the shared store.

func (*Service) Authenticate

func (s *Service) Authenticate(input LoginInput, now time.Time) (Session, error)

Authenticate validates credentials and enforces TOTP only for users who enabled it.

Note: preferAuthenticateWithContext from request handlers so the underlying user-store and session-store calls inherit request cancellation.

func (*Service) AuthenticateWithContext

func (s *Service) AuthenticateWithContext(ctx context.Context, input LoginInput, now time.Time) (Session, error)

func (*Service) BootstrapUser

func (s *Service) BootstrapUser(input BootstrapInput, now time.Time) (User, string, error)

BootstrapUser creates a local user with TOTP disabled by default.

Note: callers that have a request context should use BootstrapUserWithContext to propagate cancellation through the user store. This wrapper stays for CLI bootstrap and tests where no request ctx exists.

func (*Service) BootstrapUserWithContext

func (s *Service) BootstrapUserWithContext(ctx context.Context, input BootstrapInput, now time.Time) (User, string, error)

BootstrapUserWithContext is the ctx-aware variant of BootstrapUser.

func (*Service) CreateUser

func (s *Service) CreateUser(input BootstrapInput, now time.Time) (User, error)

CreateUser creates one local user account with TOTP disabled by default.

Note: preferCreateUserWithContext from request handlers.

func (*Service) CreateUserWithContext

func (s *Service) CreateUserWithContext(ctx context.Context, input BootstrapInput, now time.Time) (User, error)

CreateUserWithContext is the ctx-aware variant of CreateUser.

func (*Service) DeleteUser

func (s *Service) DeleteUser(userID string) error

DeleteUser removes one local user account and its active sessions.

Note: preferDeleteUserWithContext from request handlers.

func (*Service) DeleteUserWithContext

func (s *Service) DeleteUserWithContext(ctx context.Context, userID string) error

DeleteUserWithContext is the ctx-aware variant of DeleteUser.

func (*Service) DisableTotp

func (s *Service) DisableTotp(userID, password, totpCode string, now time.Time) (User, error)

DisableTotp disables TOTP after validating the current password and active TOTP code.

Note: preferDisableTotpWithContext from request handlers.

func (*Service) DisableTotpWithContext

func (s *Service) DisableTotpWithContext(ctx context.Context, userID, password, totpCode string, now time.Time) (User, error)

DisableTotpWithContext is the ctx-aware variant of DisableTotp.

func (*Service) EnableTotp

func (s *Service) EnableTotp(userID, password, totpCode string, now time.Time) (User, error)

EnableTotp validates a pending setup and persists it as the active user TOTP secret.

Note: preferEnableTotpWithContext from request handlers.

func (*Service) EnableTotpWithContext

func (s *Service) EnableTotpWithContext(ctx context.Context, userID, password, totpCode string, now time.Time) (User, error)

EnableTotpWithContext is the ctx-aware variant of EnableTotp.

func (*Service) GenerateTotpCode

func (s *Service) GenerateTotpCode(secret string, at time.Time) (string, error)

GenerateTotpCode derives a standard 30-second TOTP code from the stored secret.

func (*Service) GetSession

func (s *Service) GetSession(sessionID string) (Session, error)

GetSession returns the current session record for the provided identifier. Expired sessions (past the absolute lifetime cap or the idle-timeout) are reported as ErrSessionNotFound and evicted from memory. Use TouchSession to slide the idle-timeout forward during an authenticated request.

func (*Service) GetUserByID

func (s *Service) GetUserByID(userID string) (User, error)

GetUserByID returns the user record that owns the provided identifier.

Note: preferGetUserByIDWithContext from request handlers.

func (*Service) GetUserByIDWithContext

func (s *Service) GetUserByIDWithContext(ctx context.Context, userID string) (User, error)

GetUserByIDWithContext is the ctx-aware variant of GetUserByID.

func (*Service) HashPassword

func (s *Service) HashPassword(password string) (string, error)

HashPassword derives an Argon2id hash suitable for local credential storage.

func (*Service) LoadUsers

func (s *Service) LoadUsers(users []User)

LoadUsers replaces the current local-account state with the provided users.

func (*Service) Logout

func (s *Service) Logout(sessionID string) error

Logout revokes a session so it can no longer authenticate requests.

Note: preferLogoutWithContext from request handlers.

func (*Service) LogoutWithContext

func (s *Service) LogoutWithContext(ctx context.Context, sessionID string) error

LogoutWithContext is the ctx-aware variant of Logout.

func (*Service) ResetTotp

func (s *Service) ResetTotp(userID string) (User, error)

ResetTotp clears the active TOTP configuration for the provided user. Callers must verify that the authenticated principal is authorized to reset TOTP for the target user.

Note: preferResetTotpWithContext from request handlers.

func (*Service) ResetTotpWithContext

func (s *Service) ResetTotpWithContext(ctx context.Context, userID string) (User, error)

ResetTotpWithContext is the ctx-aware variant of ResetTotp.

func (*Service) RestoreSessions

func (s *Service) RestoreSessions() error

RestoreSessions loads persisted sessions into the in-memory map, discarding any that have exceeded the session TTL. This should be called during startup.

func (*Service) RevokeSessionsForUser

func (s *Service) RevokeSessionsForUser(userID string) int

RevokeSessionsForUser invalidates every active session belonging to the given user, returning the number of sessions removed. It removes entries from both the in-memory map and the persistent session store so that a subsequent GetSession rejects the old IDs. Callers should invoke this whenever a user's privileges or credentials change in a way that ought to force re-authentication (role change, forced password reset, etc.).

Note: preferRevokeSessionsForUserWithContext to thread request ctx.

func (*Service) RevokeSessionsForUserWithContext

func (s *Service) RevokeSessionsForUserWithContext(ctx context.Context, userID string) int

RevokeSessionsForUserWithContext is the ctx-aware variant of RevokeSessionsForUser.

func (*Service) SetConsumedTotpStore

func (s *Service) SetConsumedTotpStore(store storage.ConsumedTotpStore)

SetConsumedTotpStore wires the persistent replay-prevention store (Q2.U-S-17). Once set, every consumed TOTP code is mirrored to the store and the in-memory map is rebuilt from it on RestoreSessions.

func (*Service) SetNow

func (s *Service) SetNow(now func() time.Time)

SetNow overrides the clock used for time-sensitive auth checks.

func (*Service) SetSessionStore

func (s *Service) SetSessionStore(sessionStore storage.SessionStore)

SetSessionStore attaches a persistent session store to the auth service. When set, sessions are persisted on creation and loaded on restart.

func (*Service) SetVault

func (s *Service) SetVault(vault *secretvault.Vault)

SetVault wires the at-rest encryption vault. Called by Server during construction so TOTP secrets are encrypted before being persisted. A nil or disabled vault keeps legacy plaintext behaviour.

func (*Service) SnapshotUsers

func (s *Service) SnapshotUsers() []User

SnapshotUsers returns a copy of the current local-account state.

func (*Service) StartTotpSetup

func (s *Service) StartTotpSetup(userID string, now time.Time) (string, error)

StartTotpSetup creates a short-lived TOTP setup secret for the provided user.

Note: preferStartTotpSetupWithContext from request handlers.

func (*Service) StartTotpSetupWithContext

func (s *Service) StartTotpSetupWithContext(ctx context.Context, userID string, now time.Time) (string, error)

StartTotpSetupWithContext is the ctx-aware variant of StartTotpSetup.

func (*Service) TouchSession

func (s *Service) TouchSession(sessionID string)

TouchSession slides the idle-timeout forward on an active session (S5). It is a no-op if the session no longer exists, if the absolute-lifetime cap has already passed, or if LastSeenAt was updated less than sessionTouchThrottle ago. The throttle prevents a busy dashboard from turning every authenticated request into a map write, while still keeping the idle window rolling at minute-level resolution.

TouchSession is in-memory only. It does NOT write to the session store: that would couple every authenticated request to a DB round-trip for a value we rebuild from CreatedAt on restart anyway. Callers should invoke it after a successful session lookup on any authenticated HTTP handler.

TouchSession is the legacy ctx-less entrypoint. New callers should use TouchSessionWithContext so the persistence side-effect inherits the request's cancellation budget.

func (*Service) TouchSessionWithContext

func (s *Service) TouchSessionWithContext(ctx context.Context, sessionID string)

TouchSessionWithContext is the ctx-aware variant of TouchSession.

func (*Service) UpdateUser

func (s *Service) UpdateUser(input UpdateUserInput, now time.Time) (User, error)

UpdateUser mutates the mutable fields of one existing local user.

Note: preferUpdateUserWithContext from request handlers.

func (*Service) UpdateUserWithContext

func (s *Service) UpdateUserWithContext(ctx context.Context, input UpdateUserInput, now time.Time) (User, error)

UpdateUserWithContext is the ctx-aware variant of UpdateUser.

func (*Service) VerifyPassword

func (s *Service) VerifyPassword(hash, password string) error

VerifyPassword validates a plaintext password against an Argon2id hash.

type Session

type Session struct {
	ID         string
	UserID     string
	CreatedAt  time.Time
	LastSeenAt time.Time
}

Session stores the authenticated session record returned after login.

LastSeenAt is an in-memory sliding-refresh timestamp (S5). It is not persisted to storage: on control-plane restart we reload the session from SessionRecord and seed LastSeenAt = CreatedAt. This is a small privacy/correctness trade-off: the idle-timeout resets once across a restart rather than leaking a precise activity timestamp into the audit-visible SessionRecord table, and still meets the S5 goal of shrinking a stolen cookie's window.

type UpdateUserInput

type UpdateUserInput struct {
	UserID      string
	Username    string
	Role        Role
	NewPassword string
}

UpdateUserInput describes the mutable fields for one existing local user.

type User

type User struct {
	ID           string
	Username     string
	PasswordHash string
	Role         Role
	TotpEnabled  bool
	TotpSecret   string
	CreatedAt    time.Time
}

User stores the local operator identity.

Jump to

Keyboard shortcuts

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