SA Rule Expression Guide
This document is compiled from the NamesLink SA (Security Acceleration) Help Center to guide users in writing and AI-generating SA rule expressions.
1. Overview
SA rule expressions match traffic based on request characteristics and apply differentiated policies. A rule consists of a matching condition and an executing action: when a request matches the condition, the rule-level configuration takes precedence over global settings.
Limits
- A single rule configuration (condition + action) can be up to 4 KB.
- Total site-level configuration (global settings + rules + certificates) must not exceed 512 KB (security rules excluded).
- Rule name length: 1–128 characters.
- Maximum nested sub-conditions per rule: up to 20 for the Enterprise plan.
2. Expression Structure
Single expression
A single expression consists of a match field, a match operator, and a match value:
( <match field> <match operator> <match value> )
Example:
(http.host eq "www.example.com")
Compound expressions
Use logical operators to combine multiple sub-conditions:
- AND (
and): all conditions must be satisfied. - OR (
or): any condition can be satisfied.
Example:
(http.host eq "www.example.com" and ip.geoip.country eq "CN")
Nesting
SA rules support nesting an AND relationship inside an OR relationship, with a maximum nesting depth of 2 levels. Use parentheses () to control precedence:
(http.host eq "www.example.com")
or
(http.host eq "blog.example.com" and not (ip.geoip.country eq "CN"))
or
(http.host eq "login.example.com")
Match all requests
Use true to apply a rule to all requests:
true
3. Match Fields
SA match fields fall into three categories:
- Standard fields: attributes from standard protocols such as HTTP, IP, and TLS.
- Extended fields: computed values derived by SA from requests/responses.
- Original fields: raw request attributes preserved across SA processing modules.
3.1 Standard fields
| Field | Type | Description | Example |
|---|---|---|---|
http.host | String | Request hostname | www.example.com |
http.request.uri | String | URI (path + query string) | /image/cat.jpg?width=400 |
http.request.uri.path | String | URI path | /image/cat.jpg |
http.request.uri.path.extension | String | File extension | jpg |
http.request.uri.query | String | Query string | width=400&height=300 |
http.request.uri.args | Map<Array<String>> | Query parameter map | {"format":["webp"]} |
http.request.full_uri | String | Full URI (including protocol and hostname) | https://www.example.com/image/cat.jpg |
http.request.method | String | HTTP method | GET |
http.request.headers | Object | Request header map (keys are lowercase) | {"content-type":["application/json"]} |
http.request.cookies | String | Cookie map | {"sessionid":["330668"]} |
http.cookie | String | Raw Cookie header | sessionid=330688;userid=abc123 |
http.referer | String | Referer header | http://www.example.com/index |
http.user_agent | String | User-Agent header | Mozilla/5.0 |
http.request.body.form | Map<Array<String>> | Form-format request body | {"username":["admin"]} |
http.request.body.mime | String | Request body MIME type | application/json |
http.request.body.raw | String | Raw request body | ABC123 |
http.request.timestamp.sec | Integer | Unix timestamp (seconds) when SA POP receives request | 1735019278 |
http.request.version | String | HTTP protocol version | HTTP/1.1 |
http.x_forwarded_for | String | X-Forwarded-For header | 192.168.0.1, 10.10.0.1 |
ip.src | IP address | Client source IP | 192.0.2.1 |
ip.src.isp | String | ISP code | 100017 (China Telecom) |
ip.src.version | String | IP protocol version | IPv4 / IPv6 |
ip.src.region_code | String | Load balancer region | EAS |
ip.src.subdivision_1_iso_code | String | First-level subdivision | CN-ZJ |
ip.src.city | String | City code | 310000 |
ip.src.city_name | String | City name | hangzhou |
ip.src.lon | Float | Longitude | 120.12 |
ip.src.lat | Float | Latitude | 30.16 |
ip.src.postal_code | String | Postal code | 310000 |
ip.src.timezone | String | Time zone | UTC+8 |
ip.geoip.asnum | Integer | ASN number | 37963 |
ip.geoip.continent | String | Continent code | AS (Asia) |
ip.geoip.country | String | Country/region code | CN |
ssl | Boolean | Whether HTTPS is used | true |
Common country/region codes
| Code | Meaning |
|---|---|
CN | Chinese mainland |
US | United States |
HK | Hong Kong, China |
TW | Taiwan, China |
JP | Japan |
SG | Singapore |
GB | United Kingdom |
DE | Germany |
FR | France |
KR | South Korea |
Continent codes
| Code | Continent |
|---|---|
AF | Africa |
AN | Antarctica |
AS | Asia |
EU | Europe |
NA | North America |
OC | Oceania |
SA | South America |
3.2 Extended fields
| Field | Type | Description |
|---|---|---|
ali.ja3_hash | String | JA3 TLS fingerprint |
ali.ja4 | String | JA4 TLS fingerprint |
ali.js_detection.passed | Boolean | Whether JavaScript detection passed |
ali.static_resource | Boolean | Whether the request is for a static resource |
ali.tls_client_auth.cert_verified | Boolean | Whether the client certificate is verified |
ali.tls_hash | String | TLS fingerprint hash |
ali.site.name | String | SA site name |
3.3 Original fields
| Field | Type | Description |
|---|---|---|
http.request.body.raw | String | Raw HTTP request body |
4. Operators
4.1 Comparison operators
| Operator | Name | Value type | Example |
|---|---|---|---|
eq | Equal to | String / int / Boolean / IP | (http.host eq "www.example.com") |
ne | Not equal to | String / int / Boolean / IP | (http.host ne "www.example.com") |
contains | Contains | String | (http.host contains "example.com") |
not ... contains | Does not contain | String | (not http.host contains "example.com") |
matches | Matches regex | String | `(http.host matches "(www\ |
not ... matches | Does not match regex | String | `(not http.host matches "(www\ |
in | Is in | Array | (http.host in {"www.example.com" "blog.example.com"}) |
not ... in | Is not in | Array | (not http.host in {"www.example.com" "blog.example.com"}) |
starts_with | Starts with | String | (starts_with(http.host, "blog")) |
not starts_with | Does not start with | String | (not starts_with(http.host, "blog")) |
ends_with | Ends with | String | (ends_with(http.host, "cn")) |
not ends_with | Does not end with | String | (not ends_with(http.host, "cn")) |
lt | Less than | int | (ip.geoip.asnum lt 45104) |
le | Less than or equal to | int | (ip.geoip.asnum le 45104) |
gt | Greater than | int | (ip.geoip.asnum gt 45104) |
ge | Greater than or equal to | int | (ip.geoip.asnum ge 45104) |
len eq | Length equals | String | (len(http.request.cookies["session"]) eq 330688) |
len gt | Length greater than | String | (len(http.request.cookies["session"]) gt 330688) |
len lt | Length less than | String | (len(http.request.cookies["session"]) lt 330688) |
exists | Exists | String | (exists(http.request.headers["user-agent"])) |
not exists | Does not exist | String | (not exists(http.request.headers["user-agent"])) |
lower | Case-insensitive | String | (lower(http.request.uri)) |
Note:
matches(regex) is supported only in the Advanced and Enterprise plans.
4.2 Logical operators
| Operator | Name | Example |
|---|---|---|
not | Logical NOT | not (http.host eq "www.example.com") |
and | Logical AND | (http.host eq "www.example.com" and ip.geoip.country eq "CN") |
or | Logical OR | (http.host eq "www.example.com") or (ip.geoip.country eq "CN") |
4.3 Arrays and list references
The in operator uses braces {} with elements separated by spaces:
(http.host in {"www.example.com" "blog.example.com" "shop.example.com"})
You can also reference a named list created in the SA console:
(ip.src in $<LIST_NAME>)
5. Match Values
5.1 Strings
Strings are enclosed in double quotes " or single quotes '. Special characters such as backslash \ must be escaped.
(http.host eq "www.example.com")
(http.request.uri contains "/api/v1/")
5.2 Booleans
Use true or false directly, without quotes.
(ssl eq true)
5.3 Numbers
Integers and floating-point numbers are supported.
(ip.geoip.asnum ge 45104)
5.4 Arrays
Arrays use square brackets [] with comma-separated elements. However, SA rule expressions prefer the brace {} space-separated syntax for set matching.
5.5 Null values
Some fields allow empty string match values, depending on the operator. For http.request.uri.args, empty values are supported only with eq, ne, contains, and matches.
6. Transform Functions
SA rule language provides transform functions for manipulating and validating values.
| Function | Description | Format | Example |
|---|---|---|---|
concat | Concatenate strings | concat(String | Integer | Bytes | Array elements):String | concat("https://www.example.com", http.request.uri.path) |
ends_with | Ends with substring | ends_with(source, substring):Boolean | ends_with(http.request.uri.path, ".html") |
starts_with | Starts with substring | starts_with(source, substring):Boolean | starts_with(http.request.uri.path, "/api/") |
lower | Convert to lowercase | lower(String):String | lower(http.host) eq "www.example.com" |
upper | Convert to uppercase | upper(String):String | upper(http.host) |
regex_replace | Regex replacement | regex_replace(source, regex, replacement):String | regex_replace(http.request.uri.path, "/cat/(.*)$", "/dog/${1}") |
wildcard_replace | Wildcard replacement | wildcard_replace(source, pattern, replacement, flags?):String | wildcard_replace(http.request.uri.path, "/*", "/apps/${1}") |
to_string | Convert to string | to_string(Integer | Boolean | IP address):String | to_string(ip.src.asnum) |
6.1 Function usage limits
- For
ends_with/starts_with, thesourceargument must be a field, not a literal string. Do not writeends_with("foo.html", ".html"). regex_replacereplaces only the first match by default; matching is case-sensitive;$in the replacement string must be escaped as$$; supports${N}capture group references (up to 8).- For
wildcard_replace, thesourcemust be a field; literal*inwildcard_patternmust be escaped as\*;\must be escaped as\\;**is invalid; setflagstosfor case-sensitive matching; uses lazy matching.
7. Common Examples
7.1 Hostname match
(http.host eq "www.example.com")
7.2 Path prefix match
(http.request.uri.path starts_with "/api/")
7.3 Static resource match
(http.request.uri.path.extension in {"jpg" "jpeg" "png" "gif" "css" "js" "webp" "svg" "ico"})
7.4 Country/region match
(ip.geoip.country eq "CN")
(not ip.geoip.country eq "CN")
7.5 IP allowlist
(ip.src in {"1.2.3.4" "5.6.7.8"})
7.6 HTTP method match
(http.request.method eq "POST")
7.7 Compound condition
(http.host eq "www.example.com" and http.request.method eq "POST" and http.request.uri.path starts_with "/api/")
7.8 Header match
(http.request.headers["x-api-key"] eq "secret-key")
(exists(http.request.headers["authorization"]))
7.9 Cookie match
(http.request.cookies["sessionid"] eq "abc123")
7.10 User-Agent match
(http.user_agent contains "bot")
7.11 HTTPS match
(ssl eq true)
7.12 Regex match
(http.request.uri.path matches "^/api/v[0-9]+/.*$")
8. Expression Builder and Editor
The SA console provides two configuration methods:
- Graphical controls: configure conditions via dropdowns and input fields; expressions are generated automatically.
- Expression editor: write expressions directly; supports parentheses and grouping symbols.
When using the expression editor:
- Wrap single expressions in parentheses.
- Use parentheses explicitly to control precedence in compound expressions.
- Escape special characters in strings correctly.
- Regular expressions must follow the PCRE standard.
9. Notes
- Field case sensitivity: fields differ in case sensitivity; verify the field properties before configuration.
- Empty string support: some fields do not allow empty string match values.
- Plan limits: regex matching and sub-condition count are limited by subscription plan.
- Performance impact: excessively long strings, deep nesting, or complex regex may affect matching performance.
- Expression length: a single rule must not exceed 4 KB.