diff --git a/reference/index.md b/reference/index.md
index afb446d1..06a0820e 100644
--- a/reference/index.md
+++ b/reference/index.md
@@ -20,13 +20,14 @@ For concept introductions, tutorials, and guides, see the [Learn](/learn) sectio
### Access & Security
-| Section | Description |
-| ---------------------------------------------- | -------------------------------------------------------------------------- |
-| [REST](./rest/overview.md) | Auto-REST interface, querying, content types, headers, WebSockets, and SSE |
-| [HTTP](./http/overview.md) | HTTP server configuration, TLS, and the `server` API |
-| [MCP](./mcp/overview.md) | Built-in Model Context Protocol server, profiles, CLI, and migration |
-| [Security](./security/overview.md) | Authentication mechanisms, certificates, and CORS/SSL configuration |
-| [Users & Roles](./users-and-roles/overview.md) | RBAC, roles configuration, and user management operations |
+| Section | Description |
+| ------------------------------------------------------------------ | -------------------------------------------------------------------------- |
+| [REST](./rest/overview.md) | Auto-REST interface, querying, content types, headers, WebSockets, and SSE |
+| [HTTP](./http/overview.md) | HTTP server configuration, TLS, and the `server` API |
+| [MCP](./mcp/overview.md) | Built-in Model Context Protocol server, profiles, CLI, and migration |
+| [Security](./security/overview.md) | Authentication mechanisms, certificates, and CORS/SSL configuration |
+| [Web Application Firewall](./web-application-firewall/overview.md) | Rule-based filtering for HTTP requests |
+| [Users & Roles](./users-and-roles/overview.md) | RBAC, roles configuration, and user management operations |
### Setup & Operation
diff --git a/reference/operations-api/operations.md b/reference/operations-api/operations.md
index e958e881..13580d63 100644
--- a/reference/operations-api/operations.md
+++ b/reference/operations-api/operations.md
@@ -815,6 +815,24 @@ Returns the full current configuration object.
---
+## Web Application Firewall
+
+
+
+Operations for managing Web Application Firewall rules and cluster-wide enforcement controls.
+
+Detailed documentation: [WAF Operations and Rule Schema](../web-application-firewall/operations.md)
+
+| Operation | Description | Role Required |
+| ---------------- | ------------------------------------------------- | ------------- |
+| `add_waf_rule` | Creates a validated WAF rule | super_user |
+| `alter_waf_rule` | Patches and revalidates an existing WAF rule | super_user |
+| `drop_waf_rule` | Deletes a WAF rule | super_user |
+| `list_waf_rules` | Returns all WAF rules | super_user |
+| `set_waf_mode` | Sets the replicated mode and/or scoring threshold | super_user |
+
+---
+
## System
Operations for restarting Harper and managing system state.
diff --git a/reference/operations-api/overview.md b/reference/operations-api/overview.md
index 711d6ebb..cc335f2e 100644
--- a/reference/operations-api/overview.md
+++ b/reference/operations-api/overview.md
@@ -64,23 +64,24 @@ Operations are grouped by topic. See [Operations](./operations.md) for the compl
**Topic categories:**
-| Category | Description | Detailed Docs |
-| ------------------------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------- |
-| [Databases & Tables](./operations.md#databases--tables) | Create and manage databases, tables, and attributes | [Database Overview](../database/overview.md) |
-| [NoSQL Operations](./operations.md#nosql-operations) | Insert, update, upsert, delete, and query records | [REST Querying Reference](../rest/querying.md) |
-| [Bulk Operations](./operations.md#bulk-operations) | CSV/S3 import and export, batch delete | [Database Jobs](../database/jobs.md) |
-| [SQL Operations](./operations.md#sql-operations) | Execute SQL statements (use for investigation, not production) | — |
-| [Users & Roles](./operations.md#users--roles) | Manage users and role-based access control | [Users & Roles Operations](../users-and-roles/operations.md) |
-| [Token Authentication](./operations.md#token-authentication) | Create and refresh JWT tokens | [JWT Authentication](../security/jwt-authentication.md) |
-| [Components](./operations.md#components) | Deploy and manage Harper components | [Components Overview](../components/overview.md) |
-| [Replication & Clustering](./operations.md#replication--clustering) | Configure cluster topology and replication | [Replication & Clustering](../replication/clustering.md) |
-| [Configuration](./operations.md#configuration) | Read and update Harper configuration | — |
-| [System](./operations.md#system) | Restart, system information, status management | — |
-| [Jobs](./operations.md#jobs) | Query background job status | [Database Jobs](../database/jobs.md) |
-| [Logs](./operations.md#logs) | Read standard, transaction, and audit logs | [Logging Operations](../logging/operations.md) |
-| [Certificate Management](./operations.md#certificate-management) | Manage TLS certificates | [Certificate Management](../security/certificate-management.md) |
-| [Analytics](./operations.md#analytics) | Query analytics metrics | [Analytics Operations](../analytics/operations.md) |
-| [Registration & Licensing](./operations.md#registration--licensing) | License management | — |
+| Category | Description | Detailed Docs |
+| -------------------------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------- |
+| [Databases & Tables](./operations.md#databases--tables) | Create and manage databases, tables, and attributes | [Database Overview](../database/overview.md) |
+| [NoSQL Operations](./operations.md#nosql-operations) | Insert, update, upsert, delete, and query records | [REST Querying Reference](../rest/querying.md) |
+| [Bulk Operations](./operations.md#bulk-operations) | CSV/S3 import and export, batch delete | [Database Jobs](../database/jobs.md) |
+| [SQL Operations](./operations.md#sql-operations) | Execute SQL statements (use for investigation, not production) | — |
+| [Users & Roles](./operations.md#users--roles) | Manage users and role-based access control | [Users & Roles Operations](../users-and-roles/operations.md) |
+| [Token Authentication](./operations.md#token-authentication) | Create and refresh JWT tokens | [JWT Authentication](../security/jwt-authentication.md) |
+| [Components](./operations.md#components) | Deploy and manage Harper components | [Components Overview](../components/overview.md) |
+| [Replication & Clustering](./operations.md#replication--clustering) | Configure cluster topology and replication | [Replication & Clustering](../replication/clustering.md) |
+| [Configuration](./operations.md#configuration) | Read and update Harper configuration | — |
+| [Web Application Firewall](./operations.md#web-application-firewall) | Manage WAF rules, mode, and score threshold | [WAF Operations](../web-application-firewall/operations.md) |
+| [System](./operations.md#system) | Restart, system information, status management | — |
+| [Jobs](./operations.md#jobs) | Query background job status | [Database Jobs](../database/jobs.md) |
+| [Logs](./operations.md#logs) | Read standard, transaction, and audit logs | [Logging Operations](../logging/operations.md) |
+| [Certificate Management](./operations.md#certificate-management) | Manage TLS certificates | [Certificate Management](../security/certificate-management.md) |
+| [Analytics](./operations.md#analytics) | Query analytics metrics | [Analytics Operations](../analytics/operations.md) |
+| [Registration & Licensing](./operations.md#registration--licensing) | License management | — |
## Past Release API Documentation
diff --git a/reference/security/overview.md b/reference/security/overview.md
index 1720efdf..f62b4fae 100644
--- a/reference/security/overview.md
+++ b/reference/security/overview.md
@@ -40,6 +40,7 @@ Harper supports three authentication methods:
- For HTTP server configuration see [HTTP / Configuration / TLS](../http/tls.md)
- For Operations API configuration see [Operations API / Configuration](../configuration/operations.md)
- [Users and Roles](../users-and-roles/overview.md) — Role-Based Access Control (RBAC): defining roles, assigning permissions, and managing users.
+- [Web Application Firewall](../web-application-firewall/overview.md) — Rule-based filtering for HTTP requests before authentication and application routing.
- [Impersonation](./impersonation.md) — Execute operations as a different user or role.
## API
diff --git a/reference/web-application-firewall/configuration.md b/reference/web-application-firewall/configuration.md
new file mode 100644
index 00000000..6d70a73e
--- /dev/null
+++ b/reference/web-application-firewall/configuration.md
@@ -0,0 +1,118 @@
+---
+id: configuration
+title: Configuration
+---
+
+# WAF Configuration
+
+
+
+The WAF is configured through the top-level `waf` section of `harper-config.yaml`. Harper Pro includes an empty `waf: {}` block by default, which enables the component with its default settings.
+
+```yaml
+waf:
+ enabled: true
+ mode: enforce
+ scoreThreshold: 10
+ debounceMs: 100
+ logRateLimit: 100
+ logRateIntervalMs: 60000
+ region: us-west
+ nodeTags:
+ - edge
+ - canary
+```
+
+Changes to `harper-config.yaml` require a restart. Rule changes and global mode changes made through the [WAF Operations](./operations.md) do not.
+
+## Options
+
+### `waf.enabled`
+
+Type: `boolean`
+
+Default: `true`
+
+Enables the WAF component. Set this to `false` to disable WAF middleware and WAF management operations on this node.
+
+### `waf.mode`
+
+Type: `string`
+
+Default: `enforce`
+
+Fallback enforcement mode when no replicated WAF control value has been set:
+
+- `enforce` - Apply `block` and `score` actions.
+- `monitor` - Evaluate rules, but downgrade all `block` and `score` matches to would-block logs.
+- `off` - Do not evaluate rules.
+
+A mode set through [`set_waf_mode`](./operations.md#set_waf_mode) is stored in the replicated WAF control row and takes precedence over this node-local setting.
+
+### `waf.scoreThreshold`
+
+Type: `number`
+
+Default: `10`
+
+Fallback total at which matched `score` rules block a request. Set this to a finite number greater than zero.
+
+A threshold set through [`set_waf_mode`](./operations.md#set_waf_mode) is replicated and takes precedence. Use the operation for a cluster so every node makes the same scoring decision.
+
+### `waf.debounceMs`
+
+Type: `number` (milliseconds)
+
+Default: `100`
+
+How long a worker waits after a rule-table change before recompiling its matcher. Additional changes during the interval are combined into the same recompile.
+
+### `waf.logRateLimit`
+
+Type: `number`
+
+Default: `100`
+
+Maximum WAF match log lines emitted per rule during each `logRateIntervalMs` window. Harper suppresses additional lines and emits a summary when the next window begins.
+
+This limit affects logging only. It does not change matching or enforcement.
+
+### `waf.logRateIntervalMs`
+
+Type: `number` (milliseconds)
+
+Default: `60000`
+
+Window used by the per-rule WAF log rate limiter.
+
+### `waf.region`
+
+Type: `string`
+
+Default: None
+
+This node's region for rule [`activation.regions`](./operations.md#activation) matching.
+
+### `waf.nodeTags`
+
+Type: `string[]`
+
+Default: `[]`
+
+This node's tags for rule [`activation.tags`](./operations.md#activation) matching. A tag selector matches when at least one rule tag appears in this array.
+
+## Runtime control precedence
+
+For `mode` and `scoreThreshold`, Harper uses the first available value:
+
+1. Replicated control value set by `set_waf_mode`
+2. Local `waf` configuration
+3. Built-in default
+
+The remaining options are node-local configuration.
+
+## Related
+
+- [WAF Overview](./overview.md)
+- [WAF Operations and Rule Schema](./operations.md)
+- [Configuration Overview](../configuration/overview.md)
diff --git a/reference/web-application-firewall/operations.md b/reference/web-application-firewall/operations.md
new file mode 100644
index 00000000..0c4f0e1d
--- /dev/null
+++ b/reference/web-application-firewall/operations.md
@@ -0,0 +1,335 @@
+---
+id: operations
+title: Operations and Rule Schema
+---
+
+# WAF Operations and Rule Schema
+
+
+
+WAF rules are managed through dedicated Operations API operations. Generic CRUD operations cannot write the `system.hdb_waf_rules` system table.
+
+All operations on this page are restricted to `super_user` roles. Rule writes are attributed to the authenticated user in Harper's audit records.
+
+## Operations
+
+| Operation | Description |
+| ---------------- | --------------------------------------------------- |
+| `add_waf_rule` | Validates and creates a rule. |
+| `alter_waf_rule` | Patches and revalidates an existing rule. |
+| `drop_waf_rule` | Deletes a rule. |
+| `list_waf_rules` | Returns all rules. |
+| `set_waf_mode` | Changes the replicated mode and/or score threshold. |
+
+Rule and control changes propagate through the replicated rule table and trigger a live matcher recompile. A Harper restart is not required.
+
+## `add_waf_rule`
+
+Validates and inserts the supplied `rule`. The `id` must not already exist.
+
+When `provenance` is omitted, Harper records the rule as human-authored and sets `provenance.approver` to the authenticated username.
+
+### Request
+
+```json
+{
+ "operation": "add_waf_rule",
+ "rule": {
+ "id": "block-admin-from-scanner-network",
+ "enabled": true,
+ "priority": 100,
+ "phase": "request",
+ "description": "Block a known scanner network from the admin application",
+ "match": {
+ "path": {
+ "prefix": "/admin/"
+ },
+ "ip": ["203.0.113.0/24"]
+ },
+ "action": "block",
+ "blockStatus": 403
+ }
+}
+```
+
+### Response
+
+```json
+{
+ "message": "Added WAF rule block-admin-from-scanner-network"
+}
+```
+
+If the ID already exists, Harper returns `409`. Use `alter_waf_rule` to modify it.
+
+## `alter_waf_rule`
+
+Patches an existing rule. Supply `id` plus any fields to replace. Harper combines the patch with the stored rule and validates the complete result before writing it. The rule ID cannot be changed.
+
+### Request
+
+```json
+{
+ "operation": "alter_waf_rule",
+ "id": "block-admin-from-scanner-network",
+ "shadow": true,
+ "description": "Preview this block before enforcing it"
+}
+```
+
+### Response
+
+```json
+{
+ "message": "Updated WAF rule block-admin-from-scanner-network"
+}
+```
+
+Nested objects are replaced, not deeply patched. To change one property inside `match`, `activation`, `scope`, `provenance`, or `rateLimit`, send the complete replacement object.
+
+## `drop_waf_rule`
+
+Deletes an existing rule.
+
+### Request
+
+```json
+{
+ "operation": "drop_waf_rule",
+ "id": "block-admin-from-scanner-network"
+}
+```
+
+### Response
+
+```json
+{
+ "message": "Dropped WAF rule block-admin-from-scanner-network"
+}
+```
+
+## `list_waf_rules`
+
+Returns all stored WAF rules. The internal global-control record is not included.
+
+### Request
+
+```json
+{
+ "operation": "list_waf_rules"
+}
+```
+
+### Response
+
+```json
+[
+ {
+ "id": "log-suspicious-agent",
+ "enabled": true,
+ "priority": 200,
+ "phase": "request",
+ "match": {
+ "headers": [
+ {
+ "name": "user-agent",
+ "op": "contains",
+ "value": "ExampleScanner"
+ }
+ ]
+ },
+ "action": "log",
+ "provenance": {
+ "origin": "human",
+ "approver": "admin"
+ }
+ }
+]
+```
+
+## `set_waf_mode`
+
+Sets the cluster-wide enforcement `mode`, `scoreThreshold`, or both. At least one must be supplied. When only one field is supplied, Harper preserves the existing value of the other field.
+
+The control record is stored with the WAF rules and replicates to the other nodes. It overrides node-local `waf.mode` and `waf.scoreThreshold` configuration.
+
+### Parameters
+
+| Parameter | Required | Type | Description |
+| ---------------- | -------- | ------ | ------------------------------------------------ |
+| `operation` | Yes | string | Must be `"set_waf_mode"`. |
+| `mode` | No | string | `enforce`, `monitor`, or `off`. |
+| `scoreThreshold` | No | number | Finite positive score total that causes a block. |
+
+### Start a monitored rollout
+
+```json
+{
+ "operation": "set_waf_mode",
+ "mode": "monitor",
+ "scoreThreshold": 20
+}
+```
+
+```json
+{
+ "message": "WAF mode set to monitor, scoreThreshold set to 20"
+}
+```
+
+### Enable enforcement
+
+```json
+{
+ "operation": "set_waf_mode",
+ "mode": "enforce"
+}
+```
+
+### Disable evaluation
+
+```json
+{
+ "operation": "set_waf_mode",
+ "mode": "off"
+}
+```
+
+`off` is a pass-through kill switch. It does not delete or disable the stored rules.
+
+## Rule schema
+
+### Top-level fields
+
+| Field | Required | Type | Default | Description |
+| ------------- | ----------- | ------- | ------- | ----------------------------------------------------------------------- |
+| `id` | Yes | string | - | Unique rule identifier. |
+| `enabled` | No | boolean | `true` | Set to `false` to keep the rule stored but exclude it from matching. |
+| `priority` | No | number | `0` | Evaluation order; lower numbers run first. Must be finite. |
+| `phase` | Yes | string | - | `request` is enforced. `requestBody` is reserved and skipped in v5.2. |
+| `description` | No | string | - | Operator-facing description. |
+| `match` | Yes | object | - | Match conditions. At least one condition is required. |
+| `action` | Yes | string | - | `block`, `log`, or `score`. Reserved actions are accepted but deferred. |
+| `score` | Conditional | number | - | Required and finite when `action` is `score`. |
+| `blockStatus` | No | number | `403` | HTTP status for `block`; must be from `400` through `599`. |
+| `shadow` | No | boolean | `false` | Logs a would-block result for `block` and `score` without enforcing it. |
+| `activation` | No | object | - | Limits which nodes arm the rule. |
+| `scope` | No | object | - | Reserved metadata only; does not restrict matching in v5.2. |
+| `provenance` | No | object | - | Authorship metadata. |
+| `rateLimit` | No | object | - | Reserved; a rule containing it is deferred in full in v5.2. |
+
+### Match fields
+
+| Field | Type | Description |
+| --------- | -------------------- | ------------------------------------------------------------------------------------------------------------ |
+| `ip` | `string \| string[]` | IPv4, IPv6, or CIDR values. Array entries are alternatives. |
+| `method` | `string[]` | HTTP methods. Matching is case-insensitive. Array entries are alternatives. |
+| `path` | object | `exact`, `prefix`, and/or RE2-compatible `regex`. Present fields are combined with AND. |
+| `headers` | object[] | Header name/value conditions. Header names are case-insensitive; all entries must match. |
+| `query` | object[] | Query parameter conditions. Names and values are percent-decoded and case-sensitive; all entries must match. |
+| `ja4` | `string \| string[]` | Reserved; defers the complete rule in v5.2. |
+| `ja4h` | `string \| string[]` | Reserved; defers the complete rule in v5.2. |
+| `model` | object | Reserved; defers the complete rule in v5.2. |
+| `agent` | object | Reserved; defers the complete rule in v5.2. |
+
+`ip`, `headers`, and `query` arrays cannot be empty. `method` must be a non-empty array. Multiple top-level match fields are combined with AND.
+
+### Header and query conditions
+
+Each `headers` or `query` entry has this shape:
+
+```json
+{
+ "name": "content-type",
+ "op": "prefix",
+ "value": "application/json"
+}
+```
+
+| Field | Required | Type | Description |
+| ------- | ----------- | ------ | ---------------------------------------------------------- |
+| `name` | Yes | string | Non-empty header or query parameter name. |
+| `op` | Yes | string | `equals`, `contains`, `prefix`, `regex`, or `exists`. |
+| `value` | Conditional | string | Required and non-empty for every operator except `exists`. |
+
+For repeated headers or query parameters, a condition succeeds if any value matches.
+
+### `activation`
+
+```json
+{
+ "activation": {
+ "nodes": ["edge-1", "edge-2"],
+ "regions": ["us-west"],
+ "tags": ["canary", "public"]
+ }
+}
+```
+
+Each present selector must be a non-empty string array:
+
+- `nodes` - Matches this node's configured name.
+- `regions` - Matches [`waf.region`](./configuration.md#wafregion).
+- `tags` - Matches if any listed tag appears in [`waf.nodeTags`](./configuration.md#wafnodetags).
+
+All present selector types must succeed. For example, the rule above requires an allowed node name, the `us-west` region, and at least one of the two tags.
+
+### `provenance`
+
+```json
+{
+ "provenance": {
+ "origin": "managed-feed",
+ "approver": "security-team",
+ "source": "vendor-rule-set-2026-07"
+ }
+}
+```
+
+| Field | Type | Description |
+| ---------- | ------ | --------------------------------------------- |
+| `origin` | string | `human`, `managed-feed`, or `agent-proposed`. |
+| `approver` | string | Person or system that approved the rule. |
+| `source` | string | Source identifier for the rule. |
+
+Provenance is metadata and does not affect matching.
+
+### Reserved `scope`
+
+The accepted shape is:
+
+```json
+{
+ "scope": {
+ "clusters": ["production"],
+ "applications": ["storefront"],
+ "tenants": ["example"]
+ }
+}
+```
+
+These values are metadata only in v5.2. They do not limit rule enforcement and do not defer the rule.
+
+### Reserved `rateLimit`
+
+The accepted shape is:
+
+```json
+{
+ "rateLimit": {
+ "key": ["ip", "session"],
+ "limit": 100,
+ "windowMs": 60000
+ }
+}
+```
+
+Allowed `key` values are `ip`, `ja4`, `session`, `agent`, and `user`. `limit` and `windowMs` must be positive finite numbers.
+
+The complete rule is deferred in v5.2. No rate limiting is enforced.
+
+## Related
+
+- [WAF Overview](./overview.md)
+- [WAF Configuration](./configuration.md)
+- [Operations API Overview](../operations-api/overview.md)
diff --git a/reference/web-application-firewall/overview.md b/reference/web-application-firewall/overview.md
new file mode 100644
index 00000000..32c016c3
--- /dev/null
+++ b/reference/web-application-firewall/overview.md
@@ -0,0 +1,136 @@
+---
+id: overview
+title: Web Application Firewall
+---
+
+# Web Application Firewall
+
+
+
+The Harper Web Application Firewall (WAF) filters HTTP requests before authentication and application routing. Rules can match client IP addresses, HTTP methods, paths, headers, and query parameters, then block the request, log the match, or contribute to a shared risk score.
+
+WAF rules are stored in the replicated `system.hdb_waf_rules` table and managed through dedicated Operations API operations. Harper compiles the rules into an immutable in-memory matcher on each worker. Rule changes trigger a debounced recompile and an atomic matcher swap, so updates take effect without restarting Harper.
+
+:::info Harper Pro
+The WAF is available in Harper Pro.
+:::
+
+## Request coverage
+
+The WAF middleware runs before authentication on Harper's worker HTTP surfaces. This includes HTTP applications and REST traffic handled by the worker ports.
+
+The WAF does not filter the main-thread Operations API port. Protect that administrative surface with authentication, role permissions, TLS, and network access controls.
+
+The client IP used for matching is the request's socket peer address. In the standard Symphony-over-Unix-domain-socket topology, Harper recovers the original client IP from the PROXY protocol. The WAF does not trust `X-Forwarded-For`.
+
+## Rule evaluation
+
+A request matches a rule only when all conditions present in its `match` object succeed:
+
+- Values within `match.ip` and `match.method` are alternatives; any value can match.
+- Multiple `headers` or `query` entries must all match.
+- If `path` contains more than one of `exact`, `prefix`, and `regex`, all specified path conditions must match.
+- Header names are case-insensitive. Header values and query parameter names and values are case-sensitive.
+
+The v5.2 rule language supports positive matches only; it does not have a negation operator.
+
+Matched rules are evaluated from lowest `priority` number to highest. The first explicit `block` action or score total that reaches the configured threshold determines the block. Matching `log` rules are still logged even when another rule blocks the request.
+
+### Path normalization
+
+Harper normalizes both request paths and authored `path.exact` and `path.prefix` values before matching. Normalization:
+
+- Percent-decodes the path up to two times
+- Resolves `.` and `..` path segments
+- Collapses duplicate slashes
+- Preserves case and meaningful trailing slashes
+
+This prevents common encoding and traversal variants from bypassing a literal path rule. A `path.regex` expression runs against the normalized request path.
+
+:::tip Prefix boundaries
+`path.prefix` performs a string-prefix match. A prefix of `/admin` also matches `/administrator`. Use `/admin/`, an exact rule, or a regex when a path-segment boundary matters.
+:::
+
+### String operators
+
+Header and query conditions support these operators:
+
+| Operator | Behavior |
+| ---------- | ---------------------------------------------------------------- |
+| `equals` | The complete value must equal `value`. |
+| `contains` | The value must contain `value`. |
+| `prefix` | The value must start with `value`. |
+| `regex` | The value must match the RE2-compatible expression in `value`. |
+| `exists` | The named header or query parameter must be present; no `value`. |
+
+Regexes use RE2 to guarantee linear-time evaluation. Backreferences and lookaround are not supported; Harper rejects rules containing them.
+
+## Actions
+
+| Action | Behavior |
+| ------- | -------------------------------------------------------------------------------------------------------------------------- |
+| `block` | Stops request processing and returns the rule's `blockStatus`, or `403` by default. The response does not expose rule IDs. |
+| `log` | Allows the request and writes a rate-limited WAF match entry to the Harper log. |
+| `score` | Adds the rule's `score` to the request total. Harper blocks with `403` when the total reaches `scoreThreshold`. |
+
+The schema also reserves `challenge`, `serve`, and `drop` actions for future versions. In v5.2, a rule using one of these actions is stored but deferred: the entire rule is excluded from the matcher and Harper logs the reason.
+
+## Monitor and shadow modes
+
+Use monitor mode to observe how a rule set would behave before enabling enforcement:
+
+1. Set the global mode to `monitor`.
+2. Add or update rules.
+3. Review `WAF would block` and `WAF rule match (log)` entries in the Harper log.
+4. Set the global mode to `enforce`.
+
+In `monitor` mode, all `block` and `score` rules behave as shadow rules. They emit would-block logs but never reject a request. `log` rules continue to log normally.
+
+Set `shadow: true` on an individual rule for the same behavior while the global mode remains `enforce`.
+
+The global `off` mode is a pass-through kill switch. Rules remain stored but are not evaluated.
+
+See [WAF Operations](./operations.md#set_waf_mode) for changing the global mode without a restart.
+
+## Node activation
+
+The optional `activation` object supports staged or canary deployment:
+
+- `nodes` matches the node name.
+- `regions` matches [`waf.region`](./configuration.md#wafregion).
+- `tags` matches when the node has at least one listed [`waf.nodeTags`](./configuration.md#wafnodetags) value.
+
+When multiple selector types are present, the node must satisfy all of them. A rule that is not armed on a node is omitted from that node's matcher.
+
+## Failure behavior
+
+The WAF is designed to preserve availability:
+
+- If initial rule compilation fails, the affected worker passes traffic through and retries with exponential backoff.
+- If a later recompile fails, the worker keeps its previous matcher.
+- If request evaluation throws an internal error, Harper allows the request and writes a rate-limited error log.
+- Malformed rules are skipped and logged.
+- Valid rules using a reserved but unenforced feature are deferred in full rather than partially enforced.
+
+Use defense in depth for critical exposure: upstream network controls, TLS, authentication, and Harper role permissions remain necessary even when WAF rules are active.
+
+## v5.2 reserved features
+
+The v5.2 rule schema accepts several fields for forward compatibility:
+
+- `match.ja4`, `match.ja4h`, `match.model`, and `match.agent`
+- `rateLimit`
+- `challenge`, `serve`, and `drop` actions
+
+A rule using any of these fields is deferred in full and does not match or enforce in v5.2.
+
+The `scope` and `provenance` fields are metadata only. They are stored and validated but do not affect matching. In particular, `scope` does not restrict a rule; use `activation` for node-level rollout.
+
+The `requestBody` phase is also reserved. Only `request` phase rules are evaluated in v5.2.
+
+## Related
+
+- [WAF Configuration](./configuration.md)
+- [WAF Operations and Rule Schema](./operations.md)
+- [Logging](../logging/overview.md)
+- [Operations API](../operations-api/overview.md)
diff --git a/release-notes/v5-lincoln/5.2.md b/release-notes/v5-lincoln/5.2.md
index 8cea990a..776e17de 100644
--- a/release-notes/v5-lincoln/5.2.md
+++ b/release-notes/v5-lincoln/5.2.md
@@ -19,3 +19,9 @@ Vector searches combined with filters now evaluate the filter during HNSW graph
### Replicated `set_configuration`
The `set_configuration` operation now accepts `"replicated": true` to apply a configuration change to all cluster nodes in a single Operations API call, with per-node outcomes reported in the response's `replicated` array. Only cluster-appropriate parameters should be replicated — see [Configuration Operations](/reference/v5/configuration/operations#set-configuration).
+
+## Security
+
+### Web Application Firewall
+
+Harper Pro now includes a Web Application Firewall that evaluates rule-based IP/CIDR, method, path, header, and query conditions before authentication and application routing. Rules support block, log, and score actions; cluster-wide monitor and off modes; per-rule shadowing; node activation gates; live replicated updates; and RE2-backed regular expressions. See [Web Application Firewall](/reference/v5/web-application-firewall/overview).
diff --git a/sidebarsReference.ts b/sidebarsReference.ts
index 63957800..060cdf97 100644
--- a/sidebarsReference.ts
+++ b/sidebarsReference.ts
@@ -327,6 +327,29 @@ const sidebars: SidebarsConfig = {
},
],
},
+ {
+ type: 'category',
+ label: 'Web Application Firewall',
+ collapsible: false,
+ className: 'reference-category-header',
+ items: [
+ {
+ type: 'doc',
+ id: 'web-application-firewall/overview',
+ label: 'Overview',
+ },
+ {
+ type: 'doc',
+ id: 'web-application-firewall/configuration',
+ label: 'Configuration',
+ },
+ {
+ type: 'doc',
+ id: 'web-application-firewall/operations',
+ label: 'Operations & Rule Schema',
+ },
+ ],
+ },
{
type: 'category',
label: 'Users & Roles',