---
title: "Protect a Worker's public traffic"
---

> Documentation Index
> Fetch the complete documentation index at: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Protect a Worker's public traffic

Worker ingress protection inspects public requests before they reach Access or
application code. One policy covers the Worker's platform URL and all active
custom domains. Deploying a new application version does not replace this policy.

This capability is currently a preview on the local single-node and reference
Latitude profiles, with every Worker initially **Off**. Enabling the service on
an installation does not begin filtering existing Workers; an organization must
choose Observe or Enforce for each Worker.

## Start with observation

Open **Workers → your Worker → Security → Policy**. Choose **Observe**, save,
then exercise your normal application workflows. The page confirms publication
only after both the inspection profiles and the new HAProxy generation are ready.
If activation cannot be confirmed, the desired policy remains saved and the page
offers **Retry publication**.

![Worker security policy and scoped rule exceptions](/media/screenshots/worker-security.png)

| Mode    | Behavior                                                                                                                             |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Off     | No WAF inspection or configured rate limiting.                                                                                       |
| Observe | Evaluate requests and record matches and rate-limit decisions; do not block. Inspection failures also pass through and are recorded. |
| Enforce | Block matched requests with 403, rate-limited requests with 429, and requests whose inspection could not complete with 503.          |

**Decisions** shows recent matches and inspection errors. Its time window and
pagination are part of the URL. **Changes** records policy revisions, the actor,
and configuration automatically; no free-form reason is required.

## Tune a rule without bypassing protection

The managed profile uses OWASP CRS 4.25.0 through Coraza 3.7.0 and its 0.9.0
HAProxy agent. Standard sensitivity is paranoia level 1; Strict is level 2.
Optional repository/environment rules identify `.git` and `.env` probes.

Add an exception using the matching **rule ID** and a literal **path prefix**.
For example, CRS rule `920420` applies a web-form-oriented content-type allowlist.
A Worker accepting raw JPEG uploads may need an exception for that rule at
`/upload`. CRS rule `911100` restricts HTTP methods; API endpoints accepting PUT
or PATCH may need a scoped exception as well.

Other rules continue to run. A request may match several independent rules:
excluding the `.env` probe rule does not also exclude CRS's restricted-file rule.
Review the remaining decisions instead of disabling the final anomaly-score
blocking rule. Engine/evaluation rules cannot be added as tenant exceptions.

Prefixes are literal, case-sensitive request paths, not regular expressions.
`/editor/` is narrower than `/`, which covers the entire Worker. Exceptions never
bypass Access or rate limits. Each policy supports up to 20 exceptions.

## Understand what is inspected

The preview inspects the URL, query string, and request headers. **Request bodies
and responses are not inspected.** Upload bodies are not buffered for inspection,
and streaming responses remain streaming. This is not malware scanning and does
not validate uploaded content or replace application authorization.

Decisions retain a request ID, hostname, path, action, and matching rule IDs.
Query values, bodies, cookies, authorization headers, and matched payloads are
not included. Paths themselves can contain application-sensitive identifiers;
avoid putting secrets in URLs.

Requests blocked at ingress do not invoke or meter a Worker. Observe requests
that reach the runtime are metered normally. Security denials are separated from
application request metrics and logs. Internal service-binding and background
event delivery do not pass through this public HTTP policy.

## Rate limits and operating boundaries

Rate limits use the actual incoming source IP, not a client-supplied forwarding
header. Native and custom hostnames share the same per-Worker allowance. Users
behind a common NAT share a limit; set it with that in mind. A value of 0 disables
rate limiting. Counters are local, short-lived traffic controls, not durable
quotas; proxy reloads may reset them.

The inspector runs beside HAProxy with a bounded CPU and memory budget. Identical
policies share compiled rule profiles. Up to 32 distinct active or draining
profiles can be resident; previous profiles remain available while old ingress
generations drain. This is a capacity guard, not a billable organization quota.

For self-hosted evaluation, install Go on the Ansible controller, set
`waf_enabled: true` for the ingress host, and provision it. The local demo supports:

```sh
make waf-site
make waf-check
```

The check deploys a temporary Worker through Wrangler, exercises all modes,
exceptions, large streamed bodies, inspection failures, and steady 10 RPS, then
removes that Worker. Results are retained under `artifacts/waf/`.

The local WAF cannot absorb an attack that saturates the host's network link.
Higher-load capacity, reload behavior, and legitimate application workflows
remain production qualification work; successful low-rate checks are not a
volumetric DDoS guarantee.

Source: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/build/worker-security/index.mdx
