WAF
WAF custom resource reference
Group: waf.kubewaf.io
Version: v1beta1
Kind: WAF
Short name: waf
Purpose
WAF attaches RuleSets to a data-plane provider, runs the
modsecurity-proxy-wasm engine (optional PoW challenge first), and pushes
configuration over ECDS.
Spec overview
spec:
parentRefs: PolicyTargetReferences
provider:
type: EnvoyGateway | Istio | Cilium | Auto
ecdsCluster: string
ecdsService: string
istio: { workloadSelector, context }
cilium: { serviceName, serviceNamespace }
engine: ModSecurity # product engine
challenge: # optional, before WAF
enabled: bool
secret: string
secretRef: { name, key }
baseDifficulty / minDifficulty / maxDifficulty: int
header / headerValue: string
wasmHTTP / wasmSHA256: string
ruleRefs: []RuleRef
crsEnable: bool
crs: CRSTuning
logLevel: int
wasmHTTP / wasmSHA256 / wasmImage: string
metrics: WAFMetricsEngine
Use ModSecurity (modsecurity-proxy-wasm):
spec:
engine: ModSecurity
crsEnable: true # Include @owasp_crs/*.conf (CRS embedded in the wasm)SecLang from RuleSets is emitted as plugin JSON the module loads on onConfigure.
Full operator guide: WAF engine.
Challenge (Proof-of-Work)
Optional PoW filter before the WAF. Full property guide: Proof-of-Work challenge.
spec:
challenge:
enabled: true
# HMAC: operator auto-creates Secret <waf-name>-challenge-hmac (key: hmac)
# Optional: secret / secretRef to bring your own key
baseDifficulty: 18
minDifficulty: 12
maxDifficulty: 26
header: x-challenge-passed
headerValue: "1"| Field | Description |
|---|---|
enabled | Install the filter (default true when the block is present) |
secret / secretRef | Optional BYO HMAC (≥ 32 bytes); else auto-managed Secret |
baseDifficulty / min / max | PoW difficulty bounds (1–32) |
header / headerValue | Optional response header on pass |
wasmHTTP / wasmSHA256 | Optional challenge binary override |
Status: challengeEnabled, challengeSecretName.
ECDS names: challenge kubewaf/<ns>/<name>/challenge, WAF kubewaf/<ns>/<name>.
parentRefs
parentRefs:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: externalprovider
type | Slot |
|---|---|
EnvoyGateway | Extension Server hooks |
Istio | EnvoyFilter |
Cilium | CiliumEnvoyConfig |
ruleRefs
RuleSet only (not raw SecRules).
crsEnable / crs
When crsEnable: true, CRS is included with correct directive order (virtual
includes for the embedded CRS in modsecurity-proxy-wasm). Optional crs:
paranoia, anomaly thresholds, exclusions.
logLevel
Engine log level 0–7.
Wasm fields
| Field | Purpose |
|---|---|
wasmHTTP | Override HTTP(S) URL for the WAF .wasm |
wasmSHA256 | Integrity pin |
wasmImage | Optional OCI ref for docs / tooling |
Defaults when the operator hosts modules:
| Module | Path on :18002 |
|---|---|
| WAF (ModSecurity) | /wasm/modsecurity-proxy-wasm.wasm |
| Challenge | /wasm/challenge-proxy-wasm.wasm |
metrics
metrics:
name: "waf-prod"
extraLabels:
team: payments
includeRuleID: true
enableStats: trueStatus
status:
provider: EnvoyGateway
engine: ModSecurity
challengeEnabled: true
ecdsResourceName: kubewaf/shop/shop-waf
ecdsVersion: 42
slotKind: ExtensionServer
conditions:
- type: Ready
- type: ReferencesResolved| Field | Meaning |
|---|---|
provider | Data-plane attach path |
engine | Active WAF wasm implementation |
challengeEnabled | PoW filter present |
ecdsResourceName | Primary WAF ECDS name |
slotKind | Platform slot type |
Full example
apiVersion: waf.kubewaf.io/v1beta1
kind: WAF
metadata:
name: public-waf
namespace: ingress
spec:
engine: ModSecurity
challenge:
enabled: true
secretRef:
name: challenge-hmac
key: secret
baseDifficulty: 18
provider:
type: EnvoyGateway
parentRefs:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: public
ruleRefs:
- kind: RuleSet
name: baseline
namespace: platform
crsEnable: true
crs:
paranoiaLevel: 2
logLevel: 3
metrics:
extraLabels:
env: prod