OWASP API Authentication and Rate Limiting
An API must answer two questions for every request: who sends it, and how often does that sender call? Authentication answers the first question. Rate limiting answers the second. Together they protect data, keep services fast, and control costs.
The Theme Park Comparison
A theme park scans each ticket at the gate and also limits how many guests ride a coaster each hour. Without the ticket check, anyone walks in. Without the limit, the queue grows until nobody enjoys the park. APIs need both controls.
Authentication Options
| Method | How It Works | Best Use |
|---|---|---|
| API key | A long random string identifies the calling application | Simple server-to-server access with low risk |
| Bearer token (OAuth 2.0) | A short-lived token proves delegated user access | User-facing apps and partner access |
| Mutual TLS | Both sides present certificates | High-trust service-to-service traffic |
| Signed requests | The caller signs each request with a secret | Payment and financial integrations |
Authentication Rules
- Send credentials in headers. URLs end up in logs and browser history.
- Require HTTPS for every call.
- Issue short-lived tokens and support rotation and revocation.
- Give each client its own key so a single leak affects only one client.
- Limit scopes so a token opens only the needed actions.
- Store API keys hashed on the server, just like passwords.
GET /api/orders HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOi...
Why Rate Limiting Matters
Without limits, one client can send millions of requests. Attackers guess passwords, scrape databases, or overload the service. Honest clients with bugs can create the same damage by accident. Limits keep the service fair and available.
Common Limiting Methods
| Method | Plain Description |
|---|---|
| Fixed window | Allows a set number of calls per minute, then resets at the clock boundary |
| Sliding window | Counts calls over the last 60 seconds, which smooths bursts |
| Token bucket | Refills tokens at a steady rate. Each call spends one, and short bursts use saved tokens |
Token Bucket in a Picture
Refill: +5 tokens per second
|
↓
+--------------+
| [•][•][•][•] | capacity 10
+--------------+
|
Each request takes one token
Empty bucket → request rejected with status 429
Friendly Rejection Responses
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json
{"error": "Rate limit exceeded. Try again in 30 seconds."}
The Retry-After header tells well-behaved clients when to return.
What to Limit
- Requests per client, per user, and per IP address.
- Login and password reset attempts, with stricter limits.
- Expensive operations, such as report generation and searches.
- Response size, through pagination limits and maximum page sizes.
- Upload size and request body size.
Design Tips
Combine several limit types, because attackers rotate IP addresses. Return the current limit status in response headers so developers adapt. Monitor rejected requests and alert on sudden growth. Offer higher quotas to trusted customers through separate plans instead of removing limits.
Handling Failed Authentication
Return a 401 status for missing or invalid credentials and a 403 status for valid credentials without permission. Keep the message identical for every kind of failure, so attackers learn nothing about which part was wrong. Count failures per client and slow down or block sources that fail repeatedly.
Key Takeaways
- Authentication proves who calls the API.
- Short-lived, scoped tokens limit damage from theft.
- Rate limits protect availability, budgets, and login endpoints.
- Clear 429 responses help legitimate clients behave well.
