Skip to main content
Calico Cloud documentation

Attach WAF to a Gateway or route

note

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.
  • 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 targetRefsWAF coversUse when
GatewayEvery HTTPRoute bound to that GatewayYou want uniform WAF across all routes on a Gateway
HTTPRouteJust that one routeYou need per-route tuning — different paranoia level, different plugins

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

note

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:

    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.

  2. Verify the policy was accepted and programmed:

    kubectl get wafpolicy payments-api-waf -n payments
    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:

    curl -si "https://<gateway-host>/api?id=1+OR+1%3D1"
    HTTP/1.1 403 Forbidden
    content-length: 11
    content-type: text/plain

    Access denied
    tip

    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.

    caution

    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.

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​