Skip to main content
Security

Custom WAF rules

Match edge traffic by path, headers, geo, IP, and more, then log, block, challenge, bypass, or redirect.

Custom Web Application Firewall (WAF) rules let you control how the edge handles incoming requests before they reach your deployment. Rules are project-scoped: they apply to every hostname that serves that project (preview and production URLs, and custom domains).

Easel saves rule changes on the project and the edge picks them up after a short delay. You do not need to redeploy to update rules.

Where to configure

  1. Open your workspace and select the project.
  2. Go to Project settings.
  3. Scroll to Custom WAF rules.
  4. Add rules, toggle Active, reorder with Move up / Move down, and click Save rules.

Clearing all rules and saving stores an empty ruleset (no custom WAF behavior).

How matching works

  • Rule order matters: Easel evaluates active rules from top to bottom. The first rule whose conditions match applies; lower rules are not considered for that request.
  • Condition groups (OR): a rule can have multiple groups. If any group matches, the rule matches.
  • Conditions inside a group (AND): every condition in a group must be true for that group to match.
  • Negate: inverts a single condition after the operator runs. Prefer explicit operators such as Does not equal or Is not any of for new rules.

Conditions

Each condition has a type, an operator, and either a single value or a values list (one per line) for Is any of / Is not any of. Some types use a key (header name, query parameter name, or cookie name).

Types

TypeWhat is matched
Request path (normalized)URL path with consistent trailing-slash handling.
Raw pathPath as received, without that normalization step.
Route patternThe route pattern from your deployment that matched this request.
MethodHTTP method, compared in uppercase (GET, POST, …).
User-AgentThe User-Agent header.
Request headerA header by key, or legacy Name:expected in value when key is empty (first : separates name from the substring to compare).
Query string (full)Everything after ? in the URL.
Query parameterA single query parameter; set key to the parameter name.
CookieA named cookie (key), or the raw Cookie header when key is empty (substring style).
HostnameHost without port.
EnvironmentDeployment environment (production or preview).
ProtocolRequest protocol version (for example HTTP/2.0).
IP / CIDRClient IP after trusted proxy handling. Equals / Does not equal accept one IP or one CIDR. Is any of / Is not any of accept a list of IPs and/or CIDRs. String operators match against the textual IP form.
Edge regionThe edge region that handled the request (also exposed as X-Easel-Region when present).
Geo continent / countryContinent or country derived from the client IP. Comparisons are case-normalized to uppercase.
AS numberAutonomous system number (ASN) derived from the client IP.
Server action (Next.js)Matches Next-Action (and falls back to Next-Router-State-Tree if empty).

Operators

LabelOperand
EqualsSingle value
Does not equalSingle value
Is any ofValues (one per line); equality against the haystack
Is not any ofValues (one per line)
Starts with / Does not start withSingle value
Ends with / Does not end withSingle value
Contains / Does not containSingle value
Does not contain (legacy)Same as Does not contain; kept for older saved rules
Matches expression / Does not match expressionRegular expression. Validate with a Log rule first; patterns that work in JavaScript may still fail to compile on the edge.

For a header with only a name in legacy form (no :value), Equals / Does not contain (legacy) mean present / absent for that header.

Geo and ASN

Geo country, geo continent, and ASN conditions use IP address data powered by IPLocate.io (CC BY-SA 4.0).

Trusted client IP

For IP, geo, and ASN conditions, the edge resolves the client IP from the connection that reaches Easel CDN. Easel honors X-Forwarded-For only when the request arrives through Easel’s trusted edge path (the same model used for verified bot handling). Easel ignores client-supplied forwarding headers from untrusted peers.

Actions (Then)

ActionEffect
LogRecords a firewall observation for analytics and continues to your app. Use this to validate a rule before switching to a stricter action.
Deny (403)Responds with 403 Forbidden; the request does not proceed to your deployment.
Challenge (PoW)Serves a browser proof-of-work checkpoint (same family of flow as Attack challenge mode). After the visitor succeeds, the edge sets a session cookie (about one hour); repeat visits from that browser skip that challenge until the session expires.
Bypass attack challengeFor matching requests, skips project-wide Attack challenge mode only. Other platform protections still apply. See WAF and attack challenge.
RedirectResponds with an HTTP redirect. Set HTTP status (3xx) and Location (absolute https://… URL recommended).
  1. Create a rule with Log and confirm traffic in observability (see below).
  2. Refine conditions until only the traffic you care about matches.
  3. Change Then to Deny, Challenge, Bypass, or Redirect as needed.

Observe first, then enforce.

Firewall observability

In the dashboard, open your project’s Edge or Observability views where firewall and edge request metrics appear. Custom WAF decisions show actions such as log, deny, challenge, bypass, and redirect.

When visitors complete or fail proof-of-work at /.well-known/easel-challenge/verify, you may also see challenge pass and challenge fail counts. Those counts reflect verification outcomes, not every page view.

Current limitations

  • No per-rule rate limiting in the dashboard yet (rules cannot throttle by request rate).
  • No time-based IP ban from rule settings in the product UI today.
  • Rules are ordered; there is no separate priority number beyond list order.
  • TLS fingerprint matching is not available yet.
  • The edge evaluates regex patterns; patterns that are valid in JavaScript may still fail to compile (validate with a Log rule first).