Apply WAF and a rate limit to one path
Create one firewall rule that scores the requests to a path with a WAF rule set and caps the rate of each client on it.
You apply a WAF rule set and a rate limit to one path of a workload, such as /api/, with one firewall rule, from Azion Console, the Azion CLI, or the API. To apply a rule set to every request, refer to Apply a rule set to every request, and to rate-limit the clients in a network list, refer to Rate-limit the addresses in a list.
A path such as an API or a login form needs protections the rest of the domain does not. WAF is billed on the requests it scores, so a rule scoped to the path scores only that traffic, and its rate limit counts only the requests to that path.
- The firewall compares the request URI with the path. A request to any other path does not match, and the rule runs nothing on it.
- On a match, Set WAF scores the request against the rule set. In Blocking mode, a request the rule set blocks receives
400. - Set Rate Limit then counts the request against the rate of its client IP address. A request beyond the burst receives
429. - A request that passes both continues to the application.
Prerequisites
Console
- A firewall bound to the workload that serves the path, with WAF turned on in its main settings. To bind it, refer to Bind a firewall to a workload, and to turn on WAF, refer to Set a firewall’s main settings.
- Access to Azion Console. Refer to Access Azion Console.
The examples protect /api/ on www.example.com with the rule set <waf-id>, on the firewall <firewall-id>. Replace them with your path, rule set, and firewall.
Create the rule for the path
The criterion is Request Uri starts with /api/, which also matches deeper paths such as /api/v1/orders. Match the URI, not the query string: an empty variable does not match, so Request Args matches .* skips every POST whose payload sits in the body. The behaviors go in a fixed order. Set WAF is one of the two behaviors that another behavior can follow, and choosing Set Rate Limit removes every behavior after it, so Set WAF comes first.
Set WAF starts in Logging, which scores, records, and serves each request, because its records show what the rule set flags on your own traffic. The rate is 10 requests per second per client IP address, with a burst of 10. Requests over the rate are queued and released at the rate, and only simultaneous requests beyond the burst receive 429. Keep the burst within ten times the rate, so the queue holds at most 10 seconds of traffic.
Console
To create the rule in Azion Console:
Access Azion Console > Firewalls, then select the firewall.
Enter api - waf and rate limit.
In the Criteria section, select the Request Uri variable, the starts with operator, and /api/ as the argument.
In the Behaviors section, select Set WAF, then your rule set and Logging as the mode.
Select Add Behavior, then Set Rate Limit. Set Rate Limit Type to Req/s and Limit By to Client IP address. Enter 10 in Average Rate Limit and 10 in Maximum Burst Size.
The rule appears in the Rules Engine tab, below the rules created before it.
Every request to /api/ is scored by the rule set and counted against the rate before it reaches the application. This rule neither scores nor counts the requests to any other path. To refuse what the rule set flags, move the mode to Blocking once 3 days of Tuning hold no request that should have been served, as Switch a rule set to blocking describes.
In the Deploy remote MCP servers use case, this section takes these values:
| Setting | Value |
|---|---|
| Name | mcp - waf and rate limit |
| Criterion | Request Uri starts with /mcp |
| Set WAF | The mcp-waf rule set in Blocking mode |
| Set Rate Limit | Req/s, Client IP address, an Average Rate Limit of 10, and a Maximum Burst Size of 20 |
| Behavior order in the API | set_waf first, then set_rate_limit |
Every request to /mcp is scored by mcp-waf and counted against the rate before it reaches the function. A request the rule set blocks answers 400 with the default Bad Request page, and a request over the rate answers 429 with the default Too Many Requests page. Neither response carries a header that names the firewall or a retry time.
In the Protect public APIs from abuse use case, this section takes these values:
| Setting | Value |
|---|---|
| Name | api - rate limit per client |
| Criterion | Request Uri starts with /v1/ |
| Behavior | Set Rate Limit alone, with Req/s, Client IP address, an Average Rate Limit of 10, and a Maximum Burst Size of 10. In the API, set_rate_limit with type second, limit_by client_ip, average_rate_limit 10, and maximum_burst_size 10 |
Each client IP address can send 10 requests per second to /v1/, with a peak of 10 more queued. The rate applies in each data center, and no response carries a rate-limit header, so a client has no signal of how long to wait.
Confirm the rule acts on the path
A rule you add reaches traffic 6 minutes 29 seconds to 9 minutes 18 seconds after you save it, and until then requests alternate between the previous answer and the new one. Repeat each check until the answers agree.
To confirm both behaviors:
-
Send 30 simultaneous requests to the path from one address:
Some of the answers print
429: the simultaneous requests beyond the burst of10. A refused request receives Azion’s default error page, and no rate-limit header:Text -
Send the same 30 requests to a path outside
/api/. None of them prints429, because the rule does not match that path. -
Send a request with an injection-shaped query string to the path:
In Logging, the application answers as usual, and the request’s
x-azion-request-idfinds its WAF record. After the move to Blocking, the same request receives:
The rule refuses the requests to /api/ beyond the burst with 429, and records what the rule set flags on the path. No response names the firewall or carries a retry time, so the x-azion-request-id of a refused request is what leads to its record. To read it, refer to Find the WAF score of a blocked request.
In the Deploy remote MCP servers use case, expect:
- The rate limit refuses a loop. Sixty
tools/listrequests sent 30 at a time, so they arrive faster than 10 per second, answer with both200and429: the rate and the burst admit some of the requests, and the firewall refuses the others.
These checks confirm the Protect public APIs from abuse use case.