kubeWAF is under active development — feedback and stars on GitHub are very welcome!
kubeWAFkubeWAF
kubeWAFmodsecurity-proxy-wasmpow-proxy-wasm

Data plane (ECDS)

How kubeWAF pushes config over ECDS to Envoy-based gateways

This guide is the authoritative description of how kubeWAF pushes config into Envoy and how Envoy Gateway, Istio, and Cilium attach the filter.

Overview

Key idea: rule updates are pure ECDS publishes. Platform-specific resources only install stubs. Engines and challenge modules are separate wasm binaries served by the operator (see WAF engine and challenge).

Architecture deep dive

What Envoy sees

ECDS resource naming

ItemValue
WAF filter namekubewaf/<namespace>/<waf-name>
Challenge filter namekubewaf/<namespace>/<waf-name>/challenge
Examplekubewaf/shop/shop-waf
Cluster for ECDSkubewaf_ecds
Cluster for wasm fetchkubewaf_wasm_code

Rule update vs slot update

Wasm binary delivery (multi-module)

Envoy must HTTP-fetch each .wasm (OCI alone is not used on pure ECDS).

# Helm values — paths default under /wasm
dataplane:
  modsecurityWasmFile: /wasm/modsecurity-proxy-wasm.wasm
  challengeWasmFile: /wasm/challenge-proxy-wasm.wasm
  # Or download once at startup:
  # modsecurityWasmSourceURL: https://…/modsecurity-proxy-wasm.wasm
  # challengeWasmSourceURL: https://…/challenge-proxy-wasm.wasm

Build monorepo artifacts:

make wasm-build   # → dist/wasm/*.wasm

Default Envoy URLs (operator Service):

http://<release>-ecds.<ns>.svc:18002/wasm/modsecurity-proxy-wasm.wasm
http://<release>-ecds.<ns>.svc:18002/wasm/challenge-proxy-wasm.wasm

Option B — Per-WAF / external URL

spec:
  engine: ModSecurity
  wasmHTTP: https://cdn.example.com/modsecurity-proxy-wasm.wasm
  wasmSHA256: "<hex>"
  challenge:
    enabled: true
    wasmHTTP: https://cdn.example.com/challenge-proxy-wasm.wasm

Operator guides: WAF engine · challenge.

Provider: Envoy Gateway

Enable Extension Server on Envoy Gateway

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyGateway
provider:
  type: Kubernetes
gateway:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
extensionManager:
  policyResources:
    - group: waf.kubewaf.io
      version: v1beta1
      kind: WAF
  hooks:
    xdsTranslator:
      post:
        - HTTPListener
        - Translation
  service:
    fqdn:
      hostname: kubewaf-ecds.kubewaf-system.svc.cluster.local
      port: 5005

Restart Envoy Gateway after changing this config.

Example WAF

apiVersion: waf.kubewaf.io/v1beta1
kind: WAF
metadata:
  name: shop-waf
  namespace: shop
spec:
  provider:
    type: EnvoyGateway
  parentRefs:
    targetRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: external
  crsEnable: true
  ruleRefs:
    - kind: RuleSet
      name: shop-rules

Full guide: Envoy Gateway Integration.

Provider: Istio

No Istio control-plane flag is required. kubeWAF creates the EnvoyFilter.

spec:
  provider:
    type: Istio
    istio:
      workloadSelector:
        istio: ingressgateway
      context: GATEWAY

Full guide: Istio Integration.

Provider: Cilium

spec:
  provider:
    type: Cilium
    cilium:
      serviceName: shop-frontend
      serviceNamespace: shop

Cilium Envoy build

Creating the CEC is always supported. Whether Wasm/ECDS filters run depends on your Cilium Envoy feature set. See Cilium Integration.

Multi-replica / HA

ComponentRuns onLeader election
ECDS gRPCevery podno
Wasm HTTPevery podno
EG Extension Serverevery podno
Dataplane sync controllerevery podno
WAF controller (status, slots, finalizers)leaderyes
Inventory metricsleaderyes

Helm defaults:

replicaCount: 2
leaderElection:
  enabled: true
podDisruptionBudget:
  enabled: true
  minAvailable: 1

Status fields

kubectl get waf shop-waf -o yaml
FieldMeaning
status.providerResolved provider
status.engineWAF engine (e.g. ModSecurity)
status.challengeEnabledPoW filter installed
status.ecdsResourceNamePrimary WAF ECDS name
status.ecdsVersionSnapshot counter
status.slotKindExtensionServer / EnvoyFilter / CiliumEnvoyConfig
status.slotNamePlatform object name (if any)
status.conditions[Ready]Overall health

Operator flags (summary)

FlagDefaultPurpose
--leader-electtrueMulti-replica safety for writes
--ecds-bind-address:18001ECDS listen
--extension-server-bind-address:5005EG hooks
--wasm-serve-bind-address:18002Multi-module wasm HTTP
--modsecurity-wasm-file / --modsecurity-wasm-source-url/wasm/modsecurity-…WAF engine
--challenge-wasm-file / --challenge-wasm-source-url/wasm/challenge-…PoW module
--ecds-service-hostchart FQDNDNS name for Envoy clusters

Migration from EnvoyExtensionPolicy

The old path that created an EnvoyExtensionPolicy with inline Wasm config is removed.

  1. Expose ECDS / extension / wasm ports (Helm chart does this).
  2. Provide a wasm binary (dataplane.wasmSourceURL or volume).
  3. Configure Envoy Gateway extensionManager (see above).
  4. Delete leftover EnvoyExtensionPolicy objects from older kubeWAF versions.
  5. Re-apply WAF resources.

E2E

Provider tests live under test/e2e/. See test/e2e/README.md.

make test-e2e-envoy-gateway
make test-e2e-istio
make test-e2e-cilium

On this page