Documentation
¶
Overview ¶
Package security provides security features for identity management including account lockout protection against brute-force attacks.
Index ¶
- Variables
- type Attempt
- type Lockout
- func (l *Lockout) Begin(ctx context.Context, identifier string) (*Attempt, error)
- func (l *Lockout) CheckAndRecord(ctx context.Context, identifier string, success bool) errordeprecated
- func (l *Lockout) Close() error
- func (l *Lockout) GetStatus(ctx context.Context, identifier string) (LockoutStatus, error)
- func (l *Lockout) IsLocked(ctx context.Context, identifier string) (bool, error)
- func (l *Lockout) RecordFailure(ctx context.Context, identifier string) error
- func (l *Lockout) RecordSuccess(ctx context.Context, identifier string) error
- func (l *Lockout) Reset(ctx context.Context, identifier string) error
- func (l *Lockout) Unlock(ctx context.Context, identifier string) error
- type LockoutConfig
- type LockoutOption
- type LockoutStatus
- type LockoutStore
- type MemoryLockoutOption
- type MemoryLockoutStore
- func (m *MemoryLockoutStore) Close() error
- func (m *MemoryLockoutStore) GetStatus(ctx context.Context, identifier string, cfg LockoutConfig) (LockoutStatus, error)
- func (m *MemoryLockoutStore) Lock(ctx context.Context, identifier string, until time.Time) error
- func (m *MemoryLockoutStore) RecordAttempt(ctx context.Context, identifier string, success bool) error
- func (m *MemoryLockoutStore) Reset(ctx context.Context, identifier string) error
- func (m *MemoryLockoutStore) Unlock(ctx context.Context, identifier string) error
- type RedisLockoutOption
- type RedisLockoutStore
- func (r *RedisLockoutStore) Close() error
- func (r *RedisLockoutStore) GetStatus(ctx context.Context, identifier string, cfg LockoutConfig) (LockoutStatus, error)
- func (r *RedisLockoutStore) Lock(ctx context.Context, identifier string, until time.Time) error
- func (r *RedisLockoutStore) RecordAttempt(ctx context.Context, identifier string, success bool) error
- func (r *RedisLockoutStore) Reset(ctx context.Context, identifier string) error
- func (r *RedisLockoutStore) Unlock(ctx context.Context, identifier string) error
Constants ¶
This section is empty.
Variables ¶
var ( ErrAccountLocked = errors.New("account is locked") ErrStorageFailure = errors.New("lockout storage failure") ErrInvalidThreshold = errors.New("invalid lockout threshold") )
Common errors returned by the lockout service.
Functions ¶
This section is empty.
Types ¶
type Attempt ¶ added in v0.14.0
type Attempt struct {
// contains filtered or unexported fields
}
Attempt is a reserved login attempt. Report the outcome of the credential check with Success or Failure; a reserved attempt that is never reported stays counted as a failure.
type Lockout ¶
type Lockout struct {
// contains filtered or unexported fields
}
Lockout provides account lockout functionality.
func NewLockout ¶
func NewLockout(store LockoutStore, opts ...LockoutOption) *Lockout
NewLockout creates a new Lockout service.
func (*Lockout) Begin ¶ added in v0.14.0
Begin reserves a login attempt before the credential is verified. It returns ErrAccountLocked, without verifying anything, when the account is locked or the attempt would exceed MaxAttempts.
The attempt is recorded as a failure first and only cleared by Success, so concurrent guesses are counted before any of them is checked: at most MaxAttempts of them are allowed to verify, however many arrive at once. Recording after the check, as CheckAndRecord does, lets a burst of parallel guesses all pass the check.
func (*Lockout) CheckAndRecord
deprecated
CheckAndRecord checks if locked, then records the attempt. Returns ErrAccountLocked if the account is locked (before or after the attempt).
Deprecated: the check and the record are separate steps, and the outcome is supplied after the credential was verified, so concurrent logins all pass the check before any failure is recorded and a burst of N parallel guesses gets up to N tries beyond MaxAttempts. Use Begin, which reserves the attempt before verification.
func (*Lockout) RecordFailure ¶
RecordFailure records a failed login attempt. Returns ErrAccountLocked if the account becomes locked.
func (*Lockout) RecordSuccess ¶
RecordSuccess records a successful login and resets the attempt counter.
type LockoutConfig ¶
type LockoutConfig struct {
// MaxAttempts is the number of failed attempts before lockout.
// Default: 5
MaxAttempts int
// LockoutDuration is how long the account stays locked.
// Default: 15 minutes
LockoutDuration time.Duration
// AttemptWindow is the time window for counting attempts.
// Attempts older than this are not counted.
// Default: 15 minutes
AttemptWindow time.Duration
// CleanupInterval is how often to clean up old attempts.
// Default: 5 minutes
CleanupInterval time.Duration
}
LockoutConfig configures the account lockout behavior.
func DefaultLockoutConfig ¶
func DefaultLockoutConfig() LockoutConfig
DefaultLockoutConfig returns sensible defaults for account lockout.
type LockoutOption ¶
type LockoutOption func(*Lockout)
LockoutOption configures a Lockout service.
func WithLockoutConfig ¶
func WithLockoutConfig(cfg LockoutConfig) LockoutOption
WithLockoutConfig sets the lockout configuration.
func WithLockoutDuration ¶
func WithLockoutDuration(d time.Duration) LockoutOption
WithLockoutDuration sets how long accounts stay locked.
func WithMaxAttempts ¶
func WithMaxAttempts(n int) LockoutOption
WithMaxAttempts sets the maximum failed attempts before lockout.
type LockoutStatus ¶
type LockoutStatus struct {
// IsLocked is true if the account is currently locked.
IsLocked bool
// FailedAttempts is the number of failed attempts in the window.
FailedAttempts int
// RemainingAttempts is how many attempts remain before lockout.
RemainingAttempts int
// LockedUntil is when the lockout expires (only set if IsLocked).
LockedUntil time.Time
// LastAttempt is when the last failed attempt occurred.
LastAttempt time.Time
}
LockoutStatus contains the current lockout state for an identifier.
type LockoutStore ¶
type LockoutStore interface {
// RecordAttempt records a login attempt (success or failure).
RecordAttempt(ctx context.Context, identifier string, success bool) error
// GetStatus returns the current lockout status for an identifier.
GetStatus(ctx context.Context, identifier string, cfg LockoutConfig) (LockoutStatus, error)
// Lock explicitly locks an account.
Lock(ctx context.Context, identifier string, until time.Time) error
// Unlock explicitly unlocks an account.
Unlock(ctx context.Context, identifier string) error
// Reset clears all attempt history for an identifier.
Reset(ctx context.Context, identifier string) error
// Close releases resources.
Close() error
}
LockoutStore defines the storage interface for lockout state.
type MemoryLockoutOption ¶
type MemoryLockoutOption func(*MemoryLockoutStore)
MemoryLockoutOption configures MemoryLockoutStore.
func WithLockoutCleanupInterval ¶
func WithLockoutCleanupInterval(d time.Duration) MemoryLockoutOption
WithLockoutCleanupInterval sets the cleanup interval.
type MemoryLockoutStore ¶
type MemoryLockoutStore struct {
// contains filtered or unexported fields
}
MemoryLockoutStore is an in-memory implementation of LockoutStore.
func NewMemoryLockoutStore ¶
func NewMemoryLockoutStore(opts ...MemoryLockoutOption) *MemoryLockoutStore
NewMemoryLockoutStore creates a new in-memory lockout store.
func (*MemoryLockoutStore) Close ¶
func (m *MemoryLockoutStore) Close() error
Close implements LockoutStore.
func (*MemoryLockoutStore) GetStatus ¶
func (m *MemoryLockoutStore) GetStatus(ctx context.Context, identifier string, cfg LockoutConfig) (LockoutStatus, error)
GetStatus implements LockoutStore.
func (*MemoryLockoutStore) RecordAttempt ¶
func (m *MemoryLockoutStore) RecordAttempt(ctx context.Context, identifier string, success bool) error
RecordAttempt implements LockoutStore.
type RedisLockoutOption ¶
type RedisLockoutOption func(*RedisLockoutStore)
RedisLockoutOption configures RedisLockoutStore.
func WithLockoutKeyPrefix ¶
func WithLockoutKeyPrefix(prefix string) RedisLockoutOption
WithLockoutKeyPrefix sets a prefix for all lockout keys in Redis.
type RedisLockoutStore ¶
type RedisLockoutStore struct {
// contains filtered or unexported fields
}
RedisLockoutStore is a Redis-backed implementation of LockoutStore. Suitable for distributed deployments.
func NewRedisLockoutStore ¶
func NewRedisLockoutStore(client redis.UniversalClient, opts ...RedisLockoutOption) *RedisLockoutStore
NewRedisLockoutStore creates a new Redis-backed lockout store.
func (*RedisLockoutStore) Close ¶
func (r *RedisLockoutStore) Close() error
Close implements LockoutStore. Note: This does NOT close the Redis client since it may be shared.
func (*RedisLockoutStore) GetStatus ¶
func (r *RedisLockoutStore) GetStatus(ctx context.Context, identifier string, cfg LockoutConfig) (LockoutStatus, error)
GetStatus implements LockoutStore.
func (*RedisLockoutStore) RecordAttempt ¶
func (r *RedisLockoutStore) RecordAttempt(ctx context.Context, identifier string, success bool) error
RecordAttempt implements LockoutStore.