Adaptive Rate Limiting & Velocity-Based Threat Detection
Mindful Auth implements adaptive rate limiting to detect and prevent distributed attacks, credential stuffing, and account takeovers. Unlike fixed rate limiting (which only tracks attempts per email), adaptive rate limiting analyzes attack patterns across multiple dimensions.
Plan Availability: Core security features work on all plan tiers (Free, Pro, Business). Audit log visibility of these events requires Business plan. Free and Pro plans get the security enforcement without the audit trail.
Six-Layer Defense System
Section titled “Six-Layer Defense System”Layer 1: Velocity-Based Rate Limiting (Distributed Attack Detection)
Section titled “Layer 1: Velocity-Based Rate Limiting (Distributed Attack Detection)”Purpose: Detect when the same email is targeted from multiple IPs in a short time window.
Use Case: Prevents distributed credential stuffing attacks where attackers use botnets or proxy networks to bypass single-IP rate limits.
Applies to: Login attempts
How it works:
- Tracks unique IPs attempting login for the same email within a 15-minute sliding window
- Calculates risk level based on unique IP count:
- Low risk (1-2 IPs): Normal behavior
- Medium risk (3-4 IPs): Unusual pattern, logged but allowed
- Critical risk (5+ IPs): Distributed attack detected, account locked for 30 minutes
Cloudflare KV Key: login_velocity:{emailHash} (global, no tenant prefix)
- Generated via
loginVelocityKey(env, email)helper - Uses centralized HMAC-SHA256 hashing for PII protection
Implementation:
const velocityCheck = await trackLoginVelocity(env, request, email);if (!velocityCheck.allowed) { return jsonResponse({ authorized: false, message: 'Too many login attempts from different locations.' }, 429, env);}Audit Events:
login_velocity_violation(riskLevel: critical) - Account locked due to velocity thresholdlogin_velocity_suspicious(riskLevel: high/medium) - Suspicious pattern detected but allowed
Layer 2: Progressive Lockout (Repeat Offender Penalties)
Section titled “Layer 2: Progressive Lockout (Repeat Offender Penalties)”Purpose: Increase lockout duration exponentially for accounts repeatedly locked due to failed login attempts.
Use Case: Deters persistent attackers by making each subsequent attack attempt more costly (longer lockout).
How it works:
- Tracks lockout count per email over 30-day retention period
- Escalates lockout duration with each violation:
- 1st lockout: 1 hour
- 2nd lockout: 4 hours
- 3rd lockout: 24 hours
- 4th+ lockout: 7 days
Cloudflare KV Key: lockout_history:{emailHash} (30-day TTL)
- Generated via
lockoutHistoryKey(env, email)helper - Uses centralized HMAC-SHA256 hashing for PII protection
Implementation:
const progressive = await trackProgressiveLockout(env, userEmail, recordId);newAttempts.lockedUntil = new Date(Date.now() + progressive.lockoutDurationMs).toISOString();User-Facing Impact:
- First-time mistake: Short 1-hour lockout (reasonable for legitimate users)
- Persistent attacks: Escalating penalties make brute-force attacks impractical
Layer 3: Geo-Anomaly Detection (Impossible Travel Detection)
Section titled “Layer 3: Geo-Anomaly Detection (Impossible Travel Detection)”Purpose: Flag suspicious login attempts from geographically distant locations in a short time window.
Use Case: Detect account takeover attempts where attacker logs in from a different country than the legitimate user.
How it works:
- Stores last 5 successful login locations (country + city) per email
- On each login attempt, compares current location to recent history
- Flags as anomaly if:
- Medium risk: Login from new country (but more than 6 hours since last login)
- High risk: Login from new country within 6 hours of last login (impossible travel)
Cloudflare KV Key: geo_history:{emailHash} (90-day retention)
- Generated via
geoHistoryKey(env, email)helper - Uses centralized HMAC-SHA256 hashing for PII protection
Requirements:
- Uses ipgeolocation.io API for IP → location lookups
- Falls back gracefully if API key missing (geo-anomaly detection disabled, no impact on login)
- Results cached in Cloudflare KV for 90 days to minimize API calls
Implementation:
const ip = request.headers.get('CF-Connecting-IP');const geoData = await getGeoForIp(env, ip);const geoAnomaly = await detectGeoAnomaly(env, email, recordId, geoData?.location?.country, geoData?.location?.city);if (geoAnomaly.anomaly) { // Log to audit but allow login (non-blocking detection) await logAuditEvent(env, request, { eventType: 'login_geo_anomaly', riskLevel: geoAnomaly.riskLevel, message: `Login from ${geoAnomaly.currentCountry} (previous: ${geoAnomaly.previousCountry})` });}Update History After Successful Login:
await updateGeoHistory(env, email, geoData?.location?.country, geoData?.location?.city);Audit Events:
login_geo_anomaly(riskLevel: high/medium) - Non-blocking detection for tenant review
Important: Geo-anomaly detection is non-blocking by design. It logs the anomaly to audit logs but does not prevent login. This is intentional because:
- Users may legitimately travel or use VPNs
- GeoIP data is not 100% accurate
- Tenants can review audit logs and manually lock accounts if needed (Business plan only)
Layer 4: Registration Velocity Tracking (Spam & Harassment Prevention)
Section titled “Layer 4: Registration Velocity Tracking (Spam & Harassment Prevention)”Purpose: Prevent spam account creation and email harassment via registration flows.
Use Case: Stops attackers from creating mass accounts or repeatedly trying to register someone else’s email to spam them with verification emails.
Applies to: Password registration (/auth/register-password) and Magic Link registration (/auth/register-magic-link)
How it works:
- IP-based limit: Max 5 registrations per IP per hour (prevents single-source spam)
- Email-based limit: Max 3 registration attempts per email per hour (prevents harassment)
- Distributed attack detection: Flags 3+ different IPs trying to register same email as suspicious, blocks at 5+ IPs
Cloudflare KV Keys:
registration_ip:{ipHash}(1-hour TTL) - Generated viaregistrationIPKey(env, ip)helperregistration_velocity:{emailHash}(1-hour TTL) - Generated viaregistrationVelocityKey(env, email)helper- Both use centralized HMAC-SHA256 hashing from
worker/src/utils/kv/kvKeys.js
Implementation:
const ipCheck = await trackRegistrationByIP(env, request);if (!ipCheck.allowed) { return jsonResponse({ success: false, message: ipCheck.message }, 429, env);}
const velocityCheck = await trackRegistrationVelocity(env, request, email);if (!velocityCheck.allowed) { return jsonResponse({ success: false, message: velocityCheck.message }, 429, env);}Audit Events:
registration_ip_banned(riskLevel: high) - IP exceeded registration limitregistration_velocity_violation(riskLevel: critical/high) - Email registration velocity exceededregistration_velocity_suspicious(riskLevel: high/medium) - Multiple IPs registering same email
Thresholds:
- IP limit: 5 registrations per hour → 1-hour ban
- Email harassment: 3 registration attempts per hour → 1-hour block
- Distributed attack: 5+ different IPs → 1-hour block
Magic Link Specific Behavior:
- Registration velocity applies at registration time (when account is created)
- Existing magic link login rate limiting (
requestMagicLink.js) remains separate (3-minute cooldown per email) - This prevents both spam account creation AND harassment via verification emails
Layer 5: Verification Resend Velocity Tracking (Email Harassment Prevention)
Section titled “Layer 5: Verification Resend Velocity Tracking (Email Harassment Prevention)”Purpose: Prevent attackers from spamming verification emails to victim’s inbox via resend verification endpoint.
Use Case: Stops email harassment attacks where an attacker repeatedly requests verification emails for someone else’s account.
Applies to: Email verification resend (/auth/resend-verification)
How it works:
- IP-based limit: Max 10 verification resend requests per IP per hour (prevents single-source spam)
- Email-based velocity: Tracks unique IPs requesting verification for same email, detects distributed harassment
- Calculates risk level:
- Low risk (1-2 IPs): Normal behavior
- High risk (3-4 IPs): Suspicious pattern, logged but allowed
- Critical risk (5+ IPs): Harassment attack detected, blocked for 1 hour
KV Keys:
resend_verification_ip:{ipHash}(1-hour TTL) - Generated viaresendVerificationIPKey(env, ip)helperresend_verification_velocity:{emailHash}(1-hour TTL) - Generated viaresendVerificationVelocityKey(env, email)helper- Both use centralized HMAC-SHA256 hashing from
worker/src/utils/kv/kvKeys.js
Implementation:
const ipCheck = await trackResendVerificationByIP(env, request);if (!ipCheck.allowed) { return jsonResponse({ success: false, message: ipCheck.message }, 429, env);}
const velocityCheck = await trackResendVerificationVelocity(env, request, email);if (!velocityCheck.allowed) { return jsonResponse({ success: false, message: velocityCheck.message }, 429, env);}Audit Events:
verification_resend_ip_banned(riskLevel: high) - IP exceeded verification request limitverification_resend_velocity_violation(riskLevel: critical) - Email harassment attack detectedverification_resend_velocity_suspicious(riskLevel: high) - Multiple IPs requesting verification
Thresholds:
- IP limit: 10 verification requests per hour → 1-hour ban
- Email harassment: 5+ different IPs → 1-hour block
- Suspicious threshold: 3+ different IPs → logged but allowed
Layer 6: Magic Link Request Velocity Tracking (Email Harassment Prevention)
Section titled “Layer 6: Magic Link Request Velocity Tracking (Email Harassment Prevention)”Purpose: Prevent attackers from spamming magic link emails to victim’s inbox via magic link login endpoint.
Use Case: Stops email harassment attacks where an attacker repeatedly requests magic links for someone else’s email.
Applies to: Magic link login request (/auth/request-magic-link)
How it works:
- IP-based limit: Max 10 magic link requests per IP per hour (prevents single-source spam)
- Email-based velocity: Tracks unique IPs requesting magic links for same email, detects distributed harassment
- Calculates risk level:
- Low risk (1-2 IPs): Normal behavior
- High risk (3-4 IPs): Suspicious pattern, logged but allowed
- Critical risk (5+ IPs): Harassment attack detected, blocked for 1 hour
KV Keys:
magic_link_request_ip:{ipHash}(1-hour TTL) - Generated viamagicLinkRequestIPKey(env, ip)helpermagic_link_request_velocity:{emailHash}(1-hour TTL) - Generated viamagicLinkRequestVelocityKey(env, email)helper- Both use centralized HMAC-SHA256 hashing from
worker/src/utils/kv/kvKeys.js
Implementation:
const ipCheck = await trackMagicLinkRequestByIP(env, request);if (!ipCheck.allowed) { return jsonResponse({ success: false, message: ipCheck.message }, 429, env);}
const velocityCheck = await trackMagicLinkRequestVelocity(env, request, email);if (!velocityCheck.allowed) { return jsonResponse({ success: false, message: velocityCheck.message }, 429, env);}Audit Events:
magic_link_request_ip_banned(riskLevel: high) - IP exceeded magic link request limitmagic_link_request_velocity_violation(riskLevel: critical) - Email harassment attack detectedmagic_link_request_velocity_suspicious(riskLevel: high) - Multiple IPs requesting magic links
Thresholds:
- IP limit: 10 magic link requests per hour → 1-hour ban
- Email harassment: 5+ different IPs → 1-hour block
- Suspicious threshold: 3+ different IPs → logged but allowed
Plan Tier Functionality
Section titled “Plan Tier Functionality”All Plans (Free, Pro, Business)
Section titled “All Plans (Free, Pro, Business)”Core Security Enforcement:
- ✅ Velocity-based rate limiting (blocks distributed attacks)
- ✅ Progressive lockout penalties (exponential backoff)
- ✅ Geo-anomaly detection (location tracking)
- ✅ Registration velocity tracking (spam & harassment prevention)
- ✅ Account locking in backend (
authentication_status = "Locked") - ✅ Cloudflare KV-based tracking (login_velocity, lockout_history, geo_history, registration limits)
- ✅ 429/403 error responses to attackers
What you get: Full protection against distributed attacks, credential stuffing, and account takeovers. Your users are secure regardless of plan tier.
Business Plan Only
Section titled “Business Plan Only”Audit Log Visibility:
- 📊
login_velocity_violationevents logged - 📊
login_velocity_suspiciousevents logged - 📊
login_geo_anomalyevents logged - 📊
login_lockedevents with lockoutCount metadata - 📊
registration_velocity_violationevents logged - 📊
registration_ip_bannedevents logged - 📊 Full Cloudflare context (IP, ASN, geo, User-Agent)
- 📊 Audit log dashboard and analytics
What you get: Everything from Free/Pro PLUS detailed audit trail for monitoring, alerting, and compliance reporting.
How It Works Technically
Section titled “How It Works Technically”When auditLogsStatus = 'Disabled' (Free/Pro plans):
if (tenantCfg.auditLogsStatus !== 'Active') { // Silently skip audit logging for non-premium tenants return;}All logAuditEvent() calls return early without writing. The security enforcement happens before audit logging, so Cloudflare KV updates and account locks proceed normally. Free/Pro tenants get protected but don’t see the audit trail.
Custom Locking Logic - All Plans
Section titled “Custom Locking Logic - All Plans”All plan tiers can implement custom account locking:
- Create backend automation (Tape, Make.com, Zapier, n8n, etc.)
- Define custom conditions (business rules, field changes, manual admin actions)
- Update
authentication_status = "Locked"in backend - Call
/auth/lock-accountendpoint to invalidate sessions (requires internal API key)
Business plan advantage:
- Can create automations that REACT to Mindful Auth’s audit log events
- Example: Auto-lock account when
login_geo_anomalydetected - Example: Flag account for review after multiple
login_velocity_suspiciousevents - Example: Permanent ban after 5+
login_lockedevents in 30 days
Free/Pro plan approach:
- Implement custom locking based on backend fields and business logic
- Manual admin review and locking when suspicious activity suspected
- Cannot automate based on Mindful Auth’s security events (no audit log access)
Both approaches use the same /auth/lock-account endpoint - audit logs are for monitoring, not for the locking mechanism itself.
Attack Scenarios & System Response
Section titled “Attack Scenarios & System Response”Scenario 1: Single-IP Brute Force
Section titled “Scenario 1: Single-IP Brute Force”Attack: Attacker tries 100 passwords from one IP address.
System Response:
- First 3 failed attempts: Normal handling, incrementing counter
- 4th failed attempt triggers standard rate limiting
- Account locked for 1 hour (1st lockout)
- Audit event:
login_locked(riskLevel: high)
Velocity tracking: Not triggered (only 1 IP)
Scenario 2: Distributed Credential Stuffing
Section titled “Scenario 2: Distributed Credential Stuffing”Attack: Attacker uses 15 different IPs to try leaked passwords (1 attempt per IP).
System Response:
- First 2 IPs: Normal attempts (low risk)
- IPs 3-4: Medium risk, logged to audit
- 5th IP triggers velocity lockout
- Account locked for 30 minutes
- Audit event:
login_velocity_violation(riskLevel: critical)
Result: Attack stopped after just 5 distributed attempts, preventing credential stuffing.
Scenario 3: Persistent Attacker (Repeat Offender)
Section titled “Scenario 3: Persistent Attacker (Repeat Offender)”Attack: Attacker repeatedly attempts to brute-force account over multiple days.
System Response:
- Day 1: Account locked for 1 hour (1st lockout)
- Day 2: Account locked for 4 hours (2nd lockout)
- Day 3: Account locked for 24 hours (3rd lockout)
- Day 4+: Account locked for 7 days (4th+ lockout)
Result: Attack becomes economically unfeasible due to exponential time penalties.
Scenario 4: Account Takeover via Stolen Credentials
Section titled “Scenario 4: Account Takeover via Stolen Credentials”Attack: Attacker logs in from Russia with correct password (user is in USA).
System Response:
- Password validates successfully
- Geo-anomaly detected: Login from Russia (previous: USA, last login 2 hours ago)
- Audit event:
login_geo_anomaly(riskLevel: high) - Business plan only - Login succeeds (non-blocking)
- Business plan: Tenant automation reacts to audit log, auto-locks account
- Free/Pro plans: Tenant uses custom backend logic/manual review to detect and lock
Result: Attack succeeds initially but can be detected and stopped:
- Business plan: Automated response via audit log triggers
- Free/Pro plans: Manual review or custom backend automation
Scenario 5: Spam Account Creation
Section titled “Scenario 5: Spam Account Creation”Attack: Attacker creates 10 accounts from one IP within 30 minutes.
System Response:
- First 5 registrations: Allowed (below IP threshold)
- 6th registration attempt triggers IP ban
- IP blocked for 1 hour
- Audit event:
registration_ip_banned(riskLevel: high)
Result: Attack stopped at 5 accounts, preventing further spam.
Scenario 6: Email Harassment via Registration
Section titled “Scenario 6: Email Harassment via Registration”Attack: Attacker repeatedly tries to register victim@example.com from different IPs to spam them with verification emails.
System Response:
- First 2 registration attempts: Allowed
- 3rd registration attempt triggers email velocity limit
- Email blocked for 1 hour (all IPs)
- Audit event:
registration_velocity_violation(riskLevel: high, reason: email_harassment)
Result: Victim receives max 2 verification emails, protected from harassment.
Scenario 7: Distributed Registration Attack (Botnet)
Section titled “Scenario 7: Distributed Registration Attack (Botnet)”Attack: Botnet uses 10 different IPs to register victim@example.com.
System Response:
- First 2 IPs: Normal registration attempts
- IPs 3-4: Medium risk, logged as suspicious
- 5th IP triggers distributed attack detection
- Email blocked for 1 hour (all IPs)
- Audit event:
registration_velocity_violation(riskLevel: critical, reason: distributed_registration_attack)
Result: Attack stopped before overwhelming victim with verification emails.
Scenario 8: Email Harassment via Verification Resend
Section titled “Scenario 8: Email Harassment via Verification Resend”Attack: Attacker repeatedly requests verification emails for victim@example.com (who already has an unverified account) using different IPs to spam their inbox.
System Response:
- First 2 IPs: Verification emails sent (low risk)
- IPs 3-4: High risk, logged as suspicious
- 5th IP triggers harassment detection
- Email blocked for 1 hour (all IPs)
- Audit event:
verification_resend_velocity_violation(riskLevel: critical, reason: verification_harassment_attack)
Result: Victim receives max 4 verification emails, protected from inbox spam.
Scenario 9: Email Harassment via Magic Link Requests
Section titled “Scenario 9: Email Harassment via Magic Link Requests”Attack: Attacker repeatedly requests magic links for victim@example.com (who has an active account) using different IPs to spam their inbox.
System Response:
- First 2 IPs: Magic links sent (low risk)
- IPs 3-4: High risk, logged as suspicious
- 5th IP triggers harassment detection
- Email blocked for 1 hour (all IPs)
- Audit event:
magic_link_request_velocity_violation(riskLevel: critical, reason: magic_link_harassment_attack)
Result: Victim receives max 4 magic link emails, protected from inbox spam.
Monitoring & Alerts
Section titled “Monitoring & Alerts”Note: Audit event monitoring requires Business plan (auditLogsStatus = 'Active'). Free and Pro plans receive the security protection but not the audit trail visibility.
Key Audit Events to Monitor
Section titled “Key Audit Events to Monitor”-
login_velocity_violation(critical)- Indicates distributed attack in progress
- Tenant should investigate if pattern repeats
- Consider permanent lockout if sustained
-
login_velocity_suspicious(high/medium)- Early warning of potential attack
- May be false positive (user on mobile + VPN)
- Monitor frequency over time
-
login_geo_anomaly(high/medium)- User logged in from unexpected location
- Could be legitimate (travel, VPN) or takeover
- Review metadata: previous country, time since last login
-
login_locked(high)- Account locked due to failed attempts
- Check if lockoutCount > 3 (repeat offender)
- Consider manual investigation
Recommended Alerting Rules
Section titled “Recommended Alerting Rules”Critical Alert (immediate action):
- 5+
login_velocity_violationevents in 24 hours for different emails (coordinated attack) - Single email with 10+
login_lockedevents in 7 days (persistent targeting)
Warning Alert (review within 24 hours):
- 20+
login_velocity_suspiciousevents in 1 hour (possible attack wave) - 10+
login_geo_anomalyevents with riskLevel=high in 6 hours (mass account takeover attempt)
Info Alert (review weekly):
- Any
login_geo_anomalyfor high-value accounts (admin users, premium customers) login_lockedevents with lockoutCount >= 3 (repeat offenders)
Why Geo-Anomaly Detection is Non-Blocking
Section titled “Why Geo-Anomaly Detection is Non-Blocking”Decision: Geo-anomaly detection logs to audit but doesn’t prevent login.
Rationale:
- GeoIP data accuracy varies (70-95% depending on provider)
- Users legitimately travel, use VPNs, mobile hotspots
- False positives would frustrate legitimate users
- Tenants have full audit logs to investigate and manually lock if needed
With these six layers of defense, Mindful Auth achieves enterprise-grade threat detection across all authentication surfaces without sacrificing user experience, available to all plan tiers.