Documentation
¶
Overview ¶
Package lockout holds the strike limiter behind both HTTP surfaces: a client that fails MaxHits times is locked out of the guarded routes for a fixed window; a success resets the strikes. webui's CSRF write routes and httpapi's bearer auth share the mechanics so the two surfaces behave identically to operators.
Index ¶
Constants ¶
const ( // DefaultMaxHits is the strike count that triggers a lockout. DefaultMaxHits = 3 // DefaultLockout is the lockout window. DefaultLockout = time.Minute // DefaultIdleKeep is the unlocked idle lifetime before pruning. DefaultIdleKeep = 10 * time.Minute // DefaultMaxKeys caps the strikes map. DefaultMaxKeys = 1024 )
Operator-parity defaults shared by both HTTP surfaces: same strike trigger, window, and memory bounds, so the dashboard's write-route limiter and the API's bearer-auth limiter behave identically to operators. Surfaces pass these (or stricter values) into Config — there is exactly one source for the numbers, so a tuning change lands on both surfaces at once.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// MaxHits is the strike count that triggers a lockout.
MaxHits int
// Lockout is the lockout window, measured from the locking strike.
Lockout time.Duration
// IdleKeep is how long an unlocked entry survives without contact
// before per-contact pruning drops it.
IdleKeep time.Duration
// MaxKeys caps the strikes map against rotating source IPs.
MaxKeys int
// Now overrides the clock (tests). nil selects time.Now.
Now func() time.Time
// OnLock fires once when a key locks out (the surface's warning log).
// nil logs nothing here.
OnLock func(key string, lockout time.Duration)
}
Config builds one Limiter. MaxHits, Lockout, IdleKeep and MaxKeys are required (each surface pins its own documented constants).
type Limiter ¶
type Limiter struct {
// contains filtered or unexported fields
}
Limiter throttles repeated failures from keyed clients. It is safe for concurrent use.
func (*Limiter) Add ¶
Add records one failed attempt for key; at MaxHits the key is locked out and OnLock (when set) fires once.
art-dupl:accept mutex prolog: Lock/defer-Unlock/pruneLocked opens every; ruling: docs/status/2026-10-05_16-02_art-dupl-t3-tail-zero-dedup-sweep.md a)3 locked section; the lock must be held by the public method, so the prolog cannot move into a helper.
func (*Limiter) Locked ¶
Locked reports the remaining lockout for key (false when none), pruning the entry on contact when it went idle past IdleKeep unlocked.
art-dupl:accept mutex prolog: Lock/defer-Unlock/pruneLocked opens every; ruling: docs/status/2026-10-05_16-02_art-dupl-t3-tail-zero-dedup-sweep.md a)3 locked section; the lock must be held by the public method, so the prolog cannot move into a helper.
func (*Limiter) Reset ¶
Reset clears key's strikes after a success.
art-dupl:accept mutex prolog: Lock/defer-Unlock/pruneLocked opens every; ruling: docs/status/2026-10-05_16-02_art-dupl-t3-tail-zero-dedup-sweep.md a)3 locked section; the lock must be held by the public method, so the prolog cannot move into a helper.