Documentation
¶
Index ¶
- Variables
- type BootstrapInput
- type LoginInput
- type Role
- type Service
- func (s *Service) Authenticate(input LoginInput, now time.Time) (Session, error)
- func (s *Service) AuthenticateWithContext(ctx context.Context, input LoginInput, now time.Time) (Session, error)
- func (s *Service) BootstrapUser(input BootstrapInput, now time.Time) (User, string, error)
- func (s *Service) BootstrapUserWithContext(ctx context.Context, input BootstrapInput, now time.Time) (User, string, error)
- func (s *Service) CreateUser(input BootstrapInput, now time.Time) (User, error)
- func (s *Service) CreateUserWithContext(ctx context.Context, input BootstrapInput, now time.Time) (User, error)
- func (s *Service) DeleteUser(userID string) error
- func (s *Service) DeleteUserWithContext(ctx context.Context, userID string) error
- func (s *Service) DisableTotp(userID, password, totpCode string, now time.Time) (User, error)
- func (s *Service) DisableTotpWithContext(ctx context.Context, userID, password, totpCode string, now time.Time) (User, error)
- func (s *Service) EnableTotp(userID, password, totpCode string, now time.Time) (User, error)
- func (s *Service) EnableTotpWithContext(ctx context.Context, userID, password, totpCode string, now time.Time) (User, error)
- func (s *Service) GenerateTotpCode(secret string, at time.Time) (string, error)
- func (s *Service) GetSession(sessionID string) (Session, error)
- func (s *Service) GetUserByID(userID string) (User, error)
- func (s *Service) GetUserByIDWithContext(ctx context.Context, userID string) (User, error)
- func (s *Service) HashPassword(password string) (string, error)
- func (s *Service) LoadUsers(users []User)
- func (s *Service) Logout(sessionID string) error
- func (s *Service) LogoutWithContext(ctx context.Context, sessionID string) error
- func (s *Service) ResetTotp(userID string) (User, error)
- func (s *Service) ResetTotpWithContext(ctx context.Context, userID string) (User, error)
- func (s *Service) RestoreSessions() error
- func (s *Service) RevokeSessionsForUser(userID string) int
- func (s *Service) RevokeSessionsForUserWithContext(ctx context.Context, userID string) int
- func (s *Service) SetConsumedTotpStore(store storage.ConsumedTotpStore)
- func (s *Service) SetNow(now func() time.Time)
- func (s *Service) SetSessionStore(sessionStore storage.SessionStore)
- func (s *Service) SetVault(vault *secretvault.Vault)
- func (s *Service) SnapshotUsers() []User
- func (s *Service) StartTotpSetup(userID string, now time.Time) (string, error)
- func (s *Service) StartTotpSetupWithContext(ctx context.Context, userID string, now time.Time) (string, error)
- func (s *Service) TouchSession(sessionID string)
- func (s *Service) TouchSessionWithContext(ctx context.Context, sessionID string)
- func (s *Service) UpdateUser(input UpdateUserInput, now time.Time) (User, error)
- func (s *Service) UpdateUserWithContext(ctx context.Context, input UpdateUserInput, now time.Time) (User, error)
- func (s *Service) VerifyPassword(hash, password string) error
- type Session
- type UpdateUserInput
- type User
Constants ¶
This section is empty.
Variables ¶
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") // 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 ¶
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 Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service provides local-account hashing, TOTP, and session issuance.
func NewServiceWithStore ¶
NewServiceWithStore constructs an auth service that persists users through the shared store.
func (*Service) Authenticate ¶
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 (*Service) BootstrapUser ¶
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 ¶
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 ¶
DeleteUser removes one local user account and its active sessions.
Note: preferDeleteUserWithContext from request handlers.
func (*Service) DeleteUserWithContext ¶
DeleteUserWithContext is the ctx-aware variant of DeleteUser.
func (*Service) DisableTotp ¶
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 ¶
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 ¶
GenerateTotpCode derives a standard 30-second TOTP code from the stored secret.
func (*Service) GetSession ¶
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 ¶
GetUserByID returns the user record that owns the provided identifier.
Note: preferGetUserByIDWithContext from request handlers.
func (*Service) GetUserByIDWithContext ¶
GetUserByIDWithContext is the ctx-aware variant of GetUserByID.
func (*Service) HashPassword ¶
HashPassword derives an Argon2id hash suitable for local credential storage.
func (*Service) LoadUsers ¶
LoadUsers replaces the current local-account state with the provided users.
func (*Service) Logout ¶
Logout revokes a session so it can no longer authenticate requests.
Note: preferLogoutWithContext from request handlers.
func (*Service) LogoutWithContext ¶
LogoutWithContext is the ctx-aware variant of Logout.
func (*Service) ResetTotp ¶
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 ¶
ResetTotpWithContext is the ctx-aware variant of ResetTotp.
func (*Service) RestoreSessions ¶
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 ¶
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 ¶
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) 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 ¶
SnapshotUsers returns a copy of the current local-account state.
func (*Service) StartTotpSetup ¶
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 ¶
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 ¶
TouchSessionWithContext is the ctx-aware variant of TouchSession.
func (*Service) UpdateUser ¶
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 ¶
VerifyPassword validates a plaintext password against an Argon2id hash.
type Session ¶
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 ¶
UpdateUserInput describes the mutable fields for one existing local user.