We're exposing a public API to the internet and expect both legitimate heavy users and malicious traffic. How would you protect it from abuse and attacks at scale without degrading service for real users?
system-design · Mid level · software-engineering
What the interviewer is really asking
Assesses layered, defense-in-depth thinking for a public API under hostile traffic — pushing protections to the edge (WAF, rate limiting, DDoS), strong authn/authz per client, and distinguishing abuse mitigation from blanket blocking that hurts real users.
What to say
- Push protection to the edge before it hits your servers: a WAF and DDoS protection at the CDN/edge to drop obvious malicious patterns (injection, L7 floods), and per-client rate limiting there so volumetric abuse is shed at the network edge, not by your app tier.
- Authenticate and authorize every request with per-client identity: API keys or OAuth tokens scoped to least privilege, per-key quotas and rate limits so one abusive client can't starve others, and validate/normalize input against a schema to block malformed and injection payloads.
- Distinguish abuse from heavy legitimate use so you don't punish real users: tier limits per plan, return clear 429s with Retry-After instead of hard-blocking, prefer challenge/throttle over outright ban for borderline traffic, and monitor per-client patterns to catch credential abuse and scraping.
What to avoid
- Relying only on a single global rate limit as the whole defense, which one client can exhaust for everyone and which does nothing against injection or credential abuse.
- Doing all filtering in the application tier so attack traffic still consumes your compute and a volumetric flood takes the service down before you can reject it.
- Blanket-blocking by IP or with aggressive limits that catch legitimate heavy users and shared-NAT traffic, hurting real customers along with attackers.
Example answers
Strong: I'd defend in layers, starting at the edge. A WAF and DDoS protection in front of the API drops injection attempts and L7 floods, and edge rate-limiting (per IP and per API key) sheds volumetric abuse before it ever reaches my servers. Then every request authenticates — API keys or OAuth tokens scoped to least privilege — with per-key quotas so one client can't starve the rest, and I validate input against a schema to reject malformed or injection payloads. Crucially I'd separate abuse from heavy legit use: tiered limits per plan, a clean 429 with Retry-After rather than a hard ban, and per-client monitoring to spot scraping or credential stuffing without blanket-blocking shared IPs.
Weak: I'd put a rate limit on the API so no one can send too many requests, and block any IP that goes over the limit.