Attach WAF to a Gateway or route
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
GlobalWAFPolicybaseline. See Set a cluster-wide baseline for Gateway WAF. - You have write access to
WAFPolicyin your namespace. - A
GatewayorHTTPRoutein 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).
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
-
Create a
WAFPolicyin your namespace pointing at the target. This example attaches to oneHTTPRoute, overriding action and paranoia; the unsetcoreRuleSet.statestill inherits from the baseline:apiVersion: applicationlayer.projectcalico.org/v3kind: WAFPolicymetadata:name: payments-api-wafnamespace: paymentsspec:targetRefs:- group: gateway.networking.k8s.iokind: HTTPRoutename: payments-apiaction: Block # override: Block even if global baseline is DetectcoreRuleSet:paranoiaLevel: 2 # stricter than the cluster default# coreRuleSet.state is unset → inherited from GlobalWAFPolicyApply it with
kubectl apply -f wafpolicy.yaml. For inheritance details, see the Overview. -
Verify the policy was accepted and programmed:
kubectl get wafpolicy payments-api-waf -n paymentsNAME ACCEPTED PROGRAMMED AGEpayments-api-waf True True 45s.status.conditionsreportsAccepted,Programmed, and validation findings. Confirm Envoy Gateway received the filter withkubectl get envoyextensionpolicies -n payments(one pertargetRefsentry). -
Test that the WAF blocks an attack:
curl -si "https://<gateway-host>/api?id=1+OR+1%3D1"HTTP/1.1 403 Forbiddencontent-length: 11content-type: text/plainAccess deniedtipIn
Detectmode the request is allowed (200), but the WAF hit is still recorded in thetigera_secure_ee_waflog index (carryinggateway_name/gateway_namespace). On this release, gateway-WAF hits are not raised as Security Events — see Observing WAF activity.cautionACCEPTED=FalsereasonValidationFailedmeans aGlobalWAFValidationPolicyis blocking your config — the status message names the policy and rule. Contact your cluster operator or see Validate configuration with Rego.
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: 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 — add app-specific detections beyond the baseline.
- Validate configuration with Rego — check the merged config against compliance guardrails.
- Troubleshooting — diagnose a policy that won't accept or program.