---
title: "Attach WAF to a Gateway or route"
description: "Attach a WAFPolicy to a Gateway or HTTPRoute to turn on WAF inspection for that target, layering namespace overrides on the cluster baseline."
product: "Calico Cloud"
version: "v24.0.0"
section: "Threat defense"
canonical_url: "https://docs.tigera.io/calico-cloud/threat/gateway-waf/attach-waf-to-a-route"
---

# Attach WAF to a Gateway or route

> **SECONDARY:** This feature is tech preview. Tech preview features may be subject to significant changes before they become GA.

Create a `WAFPolicy` in your namespace pointing at Gateway API targets — WAF inspection doesn't start automatically when the feature is enabled. It inherits the cluster baseline with namespace overrides layered on top.

## Prerequisites

- The cluster operator has created the `GlobalWAFPolicy` baseline. See [Set a cluster-wide baseline for Gateway WAF](https://docs.tigera.io/calico-cloud/threat/gateway-waf/set-a-baseline.md).
- You have write access to `WAFPolicy` in your namespace.
- A `Gateway` or `HTTPRoute` in your namespace is already receiving traffic.

## Choose a target

`WAFPolicy.spec.targetRefs[]` accepts two kinds of targets:

| `kind` in `targetRefs` | WAF covers                              | Use when                                                                |
| ---------------------- | --------------------------------------- | ----------------------------------------------------------------------- |
| `Gateway`              | Every `HTTPRoute` bound to that Gateway | You want uniform WAF across all routes on a Gateway                     |
| `HTTPRoute`            | Just that one route                     | You need per-route tuning — different paranoia level, different plugins |

Each `targetRefs` entry generates a separate `EnvoyExtensionPolicy` (max 16 entries).

> **SECONDARY:** `sectionName` scopes a `targetRefs` entry to a specific listener on a `Gateway` (or a named section), so WAF applies to just that listener rather than the whole Gateway.

## Attach a WAFPolicy

1. Create a `WAFPolicy` in your namespace pointing at the target. This example attaches to one `HTTPRoute`, overriding action and paranoia; the unset `coreRuleSet.state` still inherits from the baseline:

   ```yaml
   apiVersion: applicationlayer.projectcalico.org/v3
   kind: WAFPolicy
   metadata:
     name: payments-api-waf
     namespace: payments
   spec:
     targetRefs:
       - group: gateway.networking.k8s.io
         kind: HTTPRoute
         name: payments-api
     action: Block              # override: Block even if global baseline is Detect
     coreRuleSet:
       paranoiaLevel: 2         # stricter than the cluster default
     # coreRuleSet.state is unset → inherited from GlobalWAFPolicy
   ```

   Apply it with `kubectl apply -f wafpolicy.yaml`. For inheritance details, see the [Overview](https://docs.tigera.io/calico-cloud/threat/gateway-waf/overview.md#inheritance-namespaces-override-they-dont-restart).

2. Verify the policy was accepted and programmed:

   ```bash
   kubectl get wafpolicy payments-api-waf -n payments
   ```

   ```text
   NAME               ACCEPTED   PROGRAMMED   AGE
   payments-api-waf   True       True         45s
   ```

   `.status.conditions` reports `Accepted`, `Programmed`, and validation findings. Confirm Envoy Gateway received the filter with `kubectl get envoyextensionpolicies -n payments` (one per `targetRefs` entry).

3. Test that the WAF blocks an attack:

   ```bash
   curl -si "https://<gateway-host>/api?id=1+OR+1%3D1"
   ```

   ```text
   HTTP/1.1 403 Forbidden
   content-length: 11
   content-type: text/plain

   Access denied
   ```

   > **SUCCESS:** In `Detect` mode the request is allowed (200), but the WAF hit is still recorded in the `tigera_secure_ee_waf` log index (carrying `gateway_name`/`gateway_namespace`). On this release, gateway-WAF hits are not raised as Security Events — see [Observing WAF activity](https://docs.tigera.io/calico-cloud/threat/gateway-waf/troubleshooting.md#observing-waf-activity).

   > **WARNING:** `ACCEPTED=False` reason `ValidationFailed` means a `GlobalWAFValidationPolicy` is blocking your config — the status message names the policy and rule. Contact your cluster operator or see [Validate configuration with Rego](https://docs.tigera.io/calico-cloud/threat/gateway-waf/validate-config.md).

## Conflict resolution

Only one `WAFPolicy` may be active per target. If two in the same namespace target the same Gateway/HTTPRoute, Calico Cloud follows [GEP-713](https://gateway-api.sigs.k8s.io/geps/gep-713/): oldest `creationTimestamp` wins; the newer is marked `Accepted=False` reason `Conflicted`, and only the winner's directives are merged. Fix by deleting the newer policy or repointing its `targetRefs`.

## Next steps

- [Write custom rules with plugins](https://docs.tigera.io/calico-cloud/threat/gateway-waf/write-custom-rules.md) — add app-specific detections beyond the baseline.
- [Validate configuration with Rego](https://docs.tigera.io/calico-cloud/threat/gateway-waf/validate-config.md) — check the merged config against compliance guardrails.
- [Troubleshooting](https://docs.tigera.io/calico-cloud/threat/gateway-waf/troubleshooting.md) — diagnose a policy that won't accept or program.
