Implementing Account Lockout Policies

1. Understanding Account Lockout Purpose

GoalThreat Mitigated
Slow brute forcePassword guessing
Detect credential stuffingReused passwords from breaches
Force human attentionBot automation
Alert userNotify of suspicious activity
Warning: Pure account lockout creates DoS vector. Combine with IP throttling, CAPTCHA, and risk-based unlocks.

2. Setting Failed Login Threshold

Account TypeThresholdWindow
Standard user5–10 attempts15 min
Admin / privileged3–5 attempts15 min
Service account3 attempts5 min
High-risk (banking)3 attempts1 hour

3. Implementing Automatic Lockout

Example: Redis-backed counter

const MAX = 5, WINDOW = 900, LOCK = 1800;

async function recordFailure(userId) {
  const key = `auth:fail:${userId}`;
  const count = await redis.incr(key);
  if (count === 1) await redis.expire(key, WINDOW);
  if (count >= MAX) {
    await redis.set(`auth:lock:${userId}`, "1", "EX", LOCK);
    await notifier.lockoutEmail(userId);
  }
}

async function isLocked(userId) {
  return Boolean(await redis.get(`auth:lock:${userId}`));
}

4. Setting Lockout Duration

StrategyPattern
Fixed15 or 30 minutes
Exponential backoff5, 15, 60, 240 min per re-trigger
PermanentRequires admin / email unlock
Risk-basedLength tied to risk score

5. Implementing Manual Account Unlock

MechanismAuth Required
Admin consoleAdmin role + audit log
Self-service via email linkEmail ownership
Self-service via MFAValid second factor
Support ticketID verification

6. Using Email Notification for Lockout

Example: Lockout email payload

Subject: Your account was locked due to suspicious activity

Hi {name},
We locked your account after 5 failed login attempts from:
  IP: 198.51.100.42 (United States)
  Time: 2026-05-18 14:32 UTC
  Device: Chrome 124 on macOS

If this was you, click here to unlock: https://app/unlock?t=XYZ
If not, change your password immediately.

7. Implementing Account Unlock Flow

Self-Service Unlock

  1. User receives unlock email with signed token
  2. Click link → verify token signature + expiry (1 hour)
  3. Optional: require MFA challenge
  4. Clear failure counter and lockout key
  5. Force password reset if lockout caused by suspected breach
  6. Audit log unlock event

8. Preventing Account Enumeration via Lockout

Anti-patternFix
"Account locked" responseReturn same generic error as bad password
Different timing for locked vs unknownConstant-time path
Only locking real accountsLockout signals "account exists"
SolutionTrack failures by IP+email combo, not just username

9. Implementing IP-Based Lockout

LayerThreshold
Per IP20 failures / 15 min
Per IP + endpoint10 failures / 15 min
Per ASN500 failures / 1 hr (anti-botnet)
AllowlistOffice IPs exempt
BlocklistKnown TOR exits, abuse DBs

10. Resetting Failed Attempt Counter

TriggerAction
Successful loginDelete counter
Password resetDelete counter + lockout
Manual unlockDelete counter
Time window expiryAuto-expire via TTL