Envoy Gateway Integration¶
WAF is the recommended way to protect live HTTP (and eventually TCP/TLS) traffic with kubeWAF today.
How It Works¶
WAF is a Gateway API policy attachment resource. When you create one, the kubeWAF controller:
- Resolves all referenced RuleSets into a flat list of SecLang strings
- Creates (or updates) an
EnvoyExtensionPolicyin the same namespace - The Envoy Gateway controller sees the policy and injects a Wasm filter using the coraza-proxy-wasm module into the selected listeners/routes
- The Wasm module is initialized with your rules + CRS (if enabled)
This is the same mechanism used by Envoy Gateway for other WAF / auth / transformation policies.
Prerequisites¶
- Envoy Gateway installed and its
GatewayClassnamedeg(the default) - Gateway API CRDs present (
gateway.networking.k8s.io) - The
gateway.envoyproxy.ioCRDs installed (EnvoyExtensionPolicy, etc.)
Basic Attachment Example¶
Protect a single HTTPRoute:
apiVersion: waf.kubewaf.io/v1beta1
kind: WAF
metadata:
name: shop-waf
namespace: shop
spec:
parentRefs:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: shop-frontend
# namespace defaults to the WAF namespace
ruleRefs:
- kind: RuleSet
name: shop-rules
namespace: shop
You can also target a whole Gateway:
Or a GatewayClass (affects all gateways of that class — use carefully).
Multiple RuleSets + CRS¶
spec:
crsEnable: true
ruleRefs:
- kind: RuleSet
name: baseline
namespace: platform
- kind: RuleSet
name: shop-specific
namespace: shop
logLevel: 4
logLevel controls the verbosity of the Coraza WASM filter (0 = off, 7 = trace).
Custom Coraza WASM Image¶
If you have built a custom coraza-proxy-wasm image (e.g., with additional modules or a newer Coraza version), you can override it:
Default: ghcr.io/corazawaf/coraza-proxy-wasm:0.6.0
How Rules Are Loaded¶
The controller writes the final SecLang configuration into the EnvoyExtensionPolicy's Wasm filter configuration as a single string (or multiple configuration items).
Because the resolver already flattened everything, the Wasm module receives a complete, ready-to-compile rule set.
Observing Status¶
Relevant fields:
status.conditions[ReferencesResolved]status.conditions[Ready]- Events on the resource (the controller emits normal events on resolution failures)
Also inspect the generated EnvoyExtensionPolicy:
Common Patterns¶
Protect Everything in a Namespace¶
Create one WAF that targets the Gateway resource. All HTTPRoutes attached to that Gateway inherit the policy.
Different Policies per Route¶
Multiple WAF resources can exist. The most specific match wins (Gateway API policy precedence rules apply).
Staging vs Production¶
Use two RuleSets:
staging-strict(higher paranoia)production-balanced
Then different WAF objects reference the appropriate one, even if they protect the same backend routes.
Debugging¶
- Rules not taking effect?
- Check
ReferencesResolvedcondition - Look at Envoy Gateway logs for Wasm loading errors
-
Increase
logLeveltemporarily -
High latency after enabling WAF?
- CRS with paranoia 4 + many rules can add ~1–3 ms
-
Start with lower paranoia or exclude heavy rules
-
403 on every request?
- Usually means an initialization rule is missing or your anomaly threshold is 0
- Make sure CRS initialization rules run (id 901xxx) or that you set thresholds yourself
Limitations (Current)¶
- Only HTTP is fully supported today via
HTTPRoute - TCPRoute / TLSRoute support depends on Envoy Gateway Wasm filter capabilities
- You cannot yet inject arbitrary Wasm configuration beyond what
WAFexposes (future enhancement)
Alternative (Future): WAFInstance¶
If you are not using Envoy Gateway, the WAFInstance CRD will eventually let you deploy a standalone Envoy + Coraza sidecar or gateway proxy directly managed by kubeWAF.
Today we recommend Envoy Gateway + WAF as the path of least resistance.
Further Reading¶
Next: explore the full CRD API reference.