Akamai App & API Protector study materials
Akamai App & API Protector study resources

Rate Limiting That Punishes Shared NAT Users

Akamai App & API Protector · Put your knowledge to work in context.

All case studies

Rate Limiting That Punishes Shared NAT Users

A SaaS login endpoint POST /login is protected by a rate limit of 20 requests per minute per client IP, added after credential-stuffing attempts. A large enterprise customer reports that its users are intermittently locked out during morning login peaks. The customer's employees egress through a shared NAT with a single public IP; at peak, ~300 employees log in within a few minutes, plus background token refreshes. The security team confirms the stuffing attempts came from distributed IPs with low per-IP volume, so the per-IP limit did little against them anyway. The customer cannot change its network architecture quickly. The team wants to keep stuffing protection without locking out the NAT users.

1. Evaluate the per-IP rate limit as a control against credential stuffing and propose a replacement design.

Read the worked answer

The per-IP limit is a poor fit for both problems. Credential stuffing from distributed IPs keeps per-IP volume low, so the limit barely touches the attacker while it reliably punishes any legitimate shared-egress population. The NAT lockout is the predictable cost of keying on IP.

Replacement design - shift the key and the signal:

  • Key on account/identity, not IP. Rate-limit login attempts per username/account and per session, with progressive backoff and lockout thresholds. This directly targets stuffing (many passwords against few accounts) and is immune to NAT aggregation.
  • Add a device/session signal so token refreshes and repeat logins from an already-authenticated session don't count against the same budget as fresh credential attempts.
  • Use bot detection to score the login flow, since distributed low-and-slow stuffing is a behavior problem, not a volume problem.
  • Keep a high, generous per-IP ceiling as a coarse safety net, set well above the NAT's observed peak (the ~300-employee burst plus refreshes) so it only catches gross abuse.

This keeps stuffing protection while removing the shared-IP false positives.

2. How would you set and validate the threshold for the retained per-IP ceiling?

Read the worked answer

Set it from observed legitimate peaks with headroom, not from a guess:

  • Measure the NAT's real peak request rate to /login including token refreshes over a representative window (morning peaks, event days).
  • Set the per-IP ceiling comfortably above that peak - enough headroom that normal bursts and a modest growth in headcount don't trip it - because its job is now only to catch gross abuse, not to be the primary stuffing control.
  • Validate with a load test or replay that simulates the NAT burst plus refreshes and confirms no 429s for legitimate users.
  • Monitor 429 rates segmented by IP and by account so you can see whether the ceiling is firing on legitimate shared egress or on abuse.
  • Review after the next peak; if the ceiling is still catching the NAT, raise it and rely more on the account-keyed controls.

The account-keyed limits carry the security load; the per-IP ceiling is a backstop and should be tuned to never fire on known-good shared egress.