Configuring Web Application Firewall.

In the portal, environments using the v1 load balancer can also configure a web application firewall. This is done on the firewall page in the load balancer modal.

To get there:

  1. Environments from the main, left-hand navigation.
  2. Select the environment from the first column.
  3. Scroll down to the services tile, and click on the manage tab of the load balancer.
  4. Select the Firewall page.

The controller must be set to Enable Custom Config for the firewall config to be applied.

After enabling the Firewall Configuration, the user sees an example Rule entry.

Firewall Rule Fields

Each Rule is comprised of the following fields:

Field

Description

description

A text description of the rule, providing context or notes about what the rule is intended to do.

skip

A boolean value indicating whether the rule should be skipped (true) or processed (false).

type

Specifies the action of the rule: "allow", "deny" (connection disconnect), or "block" (HTTP 403).

expires

Optional expiration date for the rule. If set, the rule is automatically disabled after this date.

match

Determines how conditions are evaluated: "any" (at least one must match), "all" (every condition must match), or "".

sample

Optional percentage (0–100) controlling what portion of requests the rule applies to. 100 = all requests, 0 = none.

conditions

An array of conditions that must be met for the rule to apply. Each condition contains:

  • type: The type of match to perform (e.g., "ip-match").

  • operator: The comparison operator to use (e.g., "==").

  • key: Optional. A specific attribute to target within the condition type (e.g., a header name for http-header-match).

  • value: The value to compare against (e.g., an IP address). For IP addresses, both addresses and CIDRs are supported.

  • regex: When true, the value is treated as a regular expression pattern instead of a literal string. Default false.

Supported Types

The currently supported condition types are listed below. Note that the HTTP-aware types (`http-url-match`, `http-method-match`, `http-header-match`, `http-body-match`) require an HTTP or HTTPS controller. On TCP or UDP controllers, only `ip-match` and `geo-match` apply.

Type

Description

ip-match

Filters traffic based on specific IP addresses or ranges using CIDR.

geo-match

Filters traffic based on geographic origin of the request.

http-url-match

Matches requests based on the HTTP URL path, excluding the domain name.

http-method-match

Evaluates HTTP requests by their method (GET, POST, PUT, etc).

http-header-match

Matches requests based on HTTP header values.

http-body-match

Matches requests based on content within the HTTP request body.

Supported Operators

Operator

Description

==

Equal to

!=

Not equal to

*=

Contains

!*=

Does not contain

^=

Starts with

!^=

Does not start with

>

Greater than

<

Less than

>=

Greater than or equal to

<=

Less than or equal to

The numeric operators (`>`, `<`, `>=`, `<=`) compare numerically and are most useful against header values that carry numbers (e.g., `Content-Length`). Other operators perform string comparison.

Rule Types

Type

Behavior

allow

Permits traffic that matches the conditions.

deny

Disconnects the connection for traffic matching the conditions.

block

Returns an HTTP 403 Forbidden response for traffic matching conditions.

Customizing the Block Response

When using `block`, the HTTP response code can be customized on a per-rule basis using the `response.http_code` field:

{
"description": "Return 429 for rate-limited paths",
"type": "block",
"match": "any",
"response": {
"http_code": 429
},
"conditions": [
{ "type": "http-url-match", "operator": "^=", "value": "/api/" }
]
}


If `response.http_code` is omitted, `block` returns 403.

Evaluation Order

Rules are evaluated in array order. The first rule whose conditions match determines the action taken on the request. There is no implicit default `allow` or `deny`, if traffic does not match a block it simply follows through with what the load balancer or controller would have done otherwise.

For example: "allow some traffic, then deny everything else" is expressed as a narrow `allow` rule first, followed by a broad `deny` rule with `0.0.0.0/0` and `::/0`. The order matters: reversing them would deny all traffic before the `allow` rule could fire.


Example Firewall Configs

An example use case might be using http-url-match and ip-match together to constrain traffic from any non-VPN IP into a resource while simultaneously defining a DENY block for all IPs. Approved IPs requesting the resource would be able to connect, while all other traffic would be blocked. This example also uses sample to apply the rule to all requests and sets an expiration date.

[
{
"description": "Only allow VPN traffic",
"skip": false,
"type": "allow",
"match": "any",
"sample": 100,
"expires": "2026-12-31T23:59:59Z",
"conditions": [
{
"type": "http-url-match",
"operator": "==",
"value": "/resource-path"
},
{
"type": "ip-match",
"operator": "==",
"value": "10.10.24.0/24"
}
]
},
{
"description": "Deny all other traffic",
"skip": false,
"type": "deny",
"match": "any",
"conditions": [
{
"type": "ip-match",
"operator": "==",
"value": "0.0.0.0/0"
},
{
"type": "ip-match",
"operator": "==",
"value": "::/0"
}
]
}
]

Using key to target a specific HTTP header, combined with regex for pattern matching:

[
{
"description": "Block requests with suspicious user agents",
"skip": false,
"type": "block",
"match": "any",
"conditions": [
{
"type": "http-header-match",
"operator": "*=",
"key": "User-Agent",
"value": "^(curl|wget|python-requests)",
"regex": true
}
]
}
]

Using block to return a 403 for specific IPs, with a contains operator for URL matching:

[
{
"description": "Block specific IPs from admin paths",
"skip": false,
"type": "block",
"match": "all",
"conditions": [
{
"type": "ip-match",
"operator": "==",
"value": "50.234.222.10"
},
{
"type": "http-url-match",
"operator": "*=",
"value": "/admin"
}
]
},
{
"description": "Deny suspicious IPv6 address",
"skip": false,
"type": "deny",
"match": "any",
"conditions": [
{
"type": "ip-match",
"operator": "==",
"value": "2600:6b4a:223f:93cf:84a1:4afd:9221:8988"
}
]
}
]
Cookies

Cookies Preferences

We run basic, anonymous analytics by default to measure site traffic. By clicking "Accept," you allow additional cookies for advanced app improvements and tailored advertising. Choose what you share by clicking "Customize."