Can I apply rate limiting based on a key such as an API key / token?
Short answer
Yes. In the Quarantine action, Tracking Key = Manual is selected, and the Smart Variable that carries the key (e.g. Request HTTP header content for the X-API-Key header, a cookie or a query parameter) is added with fx to the Quarantine Keys to Track field; the request counter and the quarantine are kept per this value. The same job is also done with the Fields to Track field of the Advanced Traffic Inspection action, the Tracking Condition condition and the Block action, and, if AGS is on, with Policy Scope = Composite in the bot protection policy. Bot/DDoS Protection keeps volume limits for the source IP, the country, the network type or the vService as a whole; it does not give a per-key limit.
Problem: Multiple Customers Come from the Same IP
API clients often come from the same gateway or cloud egress; a per-IP limit collects these customers in a single counter, and the load of one customer also blocks the others. The usage quota needs to be applied separately for each API key or token. For the basic setup of the per-IP limit: Can I do rate limiting (X requests per second per IP)?
Solution: Three Methods
The three methods are alternatives to each other; the difference is in how long the block lasts when the limit is exceeded.
| Your situation | Suitable method |
|---|---|
| The key that exceeds the threshold should be blocked for a specific duration (Quarantine time) | Method 1: Quarantine (Tracking key = Manual) |
| The block should last only while the key is above the threshold | Method 2: Advanced Traffic Inspection + Tracking Condition + Block |
| AGS-enabled vService; a limit based on the combination of key and address | Method 3: AGS → Policy scope = Composite |
Method 1: Quarantine (Tracking Key = Manual) Recommended
- How it works The counter is kept per value of the selected variable; a key that exceeds the Quarantine Condition threshold in the Tracking Time window is met with the Quarantine Action for the Quarantine Time (10 minutes by default).
- Where it is openedLoad Balancer → Actions → Quarantine → Tracking Key = Manual
- Requirement A condition that checks the presence of the header, to separate the requests that do not send the key.
- vService type HTTP (the header, cookie and query parameter variables exist only on HTTP)
Step-by-Step Configuration
With Load Balancer → Conditions → Add, Condition Name = api-anahtari-var, Criteria = HTTP Header, Header name = X-API-Key and the matching Is present are selected, and the condition is saved with Add. This condition prevents the requests that never send the key from being collected under a single empty key.
The action form is opened with Load Balancer → Actions → Add (how to add); Action Name = api-kota, Action Type = Quarantine are selected.
Tracking Key = Manual is selected; in the Quarantine Keys to Track field, the Request HTTP header content variable is added with fx with the X-API-Key argument. If the key is in a cookie or in the query string, the Request Cookie Content or Query Parameter variable is selected (Variables).
Tracking Time = 1 minute is entered. In the Quarantine Condition field, in the form opened with (+), Criteria = Quarantine condition, Tracking Criteria = HTTP requests, Tracking operator = > and the threshold (e.g. 100) are entered and the condition is added. In this example, if a key sends more than 100 requests per minute, it is put into quarantine.
Quarantine Time is entered (10 minutes by default; 1 second – 360 hours). Quarantine Action = Show content is selected, Quarantine content is left as the default quarantine page and Status code = 429 is selected (401 by default). The default Silent Drop drops the request without giving a response.
api-anahtari-var is selected in the Conditions field. Conditions only selects the traffic on which tracking is done; all requests of the key that is put into quarantine are met with the action.
The action is saved with Add.
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and the edit form is opened with Edit.
api-kota is selected in the Details → Actions field. The action does not work unless it is added to the vService.
The form is saved with Save. In a cluster, the configuration is transferred to the peer device automatically by default (if Manual Sync Mode is on, with Synchronize); the counters and quarantine records, however, are kept separately on each device.
Verification
In the Logs & Tracking tab of the vService, the api-kota (TRACKING, …) source is opened (tracking logs).
Each API key on a separate row, with its own counterCommand: for i in $(seq 1 120); do curl -s -o /dev/null -w '%{http_code}\n' -H 'X-API-Key: test-anahtar' https://api.example.com/; done | sort | uniq -c
429 for the requests after the thresholdMethod 2: Advanced Traffic Inspection + Tracking Condition + Block
- How it worksAdvanced Traffic Inspection keeps a counter per key; Tracking Condition compares the counter with the threshold, and Block is applied only while the key is above the threshold. There is no separate quarantine duration.
- Where it is openedLoad Balancer → Actions → Advanced Traffic Inspection · Load Balancer → Conditions → Tracking Condition
- Requirement None
- vService type HTTP (the Block action exists only on HTTP)
Step-by-Step Configuration
With Load Balancer → Actions → Add, Action Name = api-sayac, Action Type = Advanced Traffic Inspection are selected; Traffic Tag = apikey is entered, Request HTTP header content (X-API-Key) is selected with fx in the Fields to track field and Tracking Period is set. The action is saved with Add.
With Load Balancer → Conditions → Add, Condition Name = api-esik, Criteria = Tracking Condition, Tracked Table = apikey, Tracking Criteria = HTTP requests, Tracking operator = > and the threshold are entered. The condition is saved with Add.
With Load Balancer → Actions → Add, Action Name = api-kota-engel, Action Type = Block, Status Code = 429 are selected; api-esik is selected in the Conditions field. The action is saved with Add.
The HTTP vService is opened with Edit.
In the Details → Actions field, first api-sayac and then api-kota-engel are selected.
The form is saved with Save.
Verification
In the Logs & Tracking tab of the vService, the Advanced Traffic Inspection tracking table is opened; requests above the threshold are sent.
A counter per key; 429 above the thresholdMethod 3: AGS → Policy Scope = Composite
- How it works An AGS policy with the Requests trigger keeps a separate counter per combination of the variables selected in the Scope Components field (e.g. the API key and the client address); when the Request Threshold is exceeded within the Trigger Window Duration, the action of the policy is applied.
- Where it is openedAGS → Protection Policies → Bot Protection Policies
- Requirement AGS license; AGS-enabled vService
- vService type HTTP
Step-by-Step Configuration
If AGS is not on in the vService, it is turned on (two ways); since the default flow denies users when AGS is turned on, the flow is prepared first: How do I attach WAF, L7 DDoS & Threat Protection and AGS to a vService?
The policy form is opened with AGS → Protection Policies → Bot Protection Policies → Add.
Bot Protection Policy Name is entered; Trigger Type = Requests, Request threshold (no default value comes in the form; an integer between 1 and 10000, e.g. 100) and Trigger window duration (1 minute by default) are entered. Policy scope = Composite is selected, and at least two variables (e.g. the X-API-Key header and the client address) are added to the Scope Components field; the rows cannot repeat. Action is selected (e.g. Deny).
The policy is saved with Add.
In the Left Monitor Panel → AGS-Enabled vServices → vService → AGS Management tab, the Edit link of the Protection section is clicked.
In the Edit / Protection window that opens, the policy is selected in the Bot Protection Policies field.
Accept is clicked; the policy is listed in the Bot Protection box in the AGS Management tab.
Verification
Requests above the threshold are sent with the same key within the window.
The action of the policy (429 with Deny)Common Mistakes
- Forgetting the requests that do not send the key. Requests with an empty value are collected under a single empty key; the presence of the header is checked with a condition, or requests without a key are separately limited per IP.
- Applying the limit to all paths. A large number of different keys fills the tracking table; the limit is applied with a condition only to the necessary API paths.
- Looking for a key-based limit in Bot/DDoS Protection. Bot/DDoS Protection keeps volume limits for the source IP, the country, the network type or the vService as a whole; a key-based limit is done with Quarantine, Advanced Traffic Inspection or AGS.
- Checking the table of a single device in a cluster. Counters and quarantine records are kept per device; the threshold is counted separately on each device.
How it is done in the documentation
