Gateway Adapters

Go-first self-hosted gateway adapters for NGINX, Envoy, and Kubernetes, decoupling protocol translation from the core detection engine.

CheeseWAF-Adapters provides Go-first, self-hosted gateway adapters for CheeseWAF. It completely separates gateway-specific glue code from the core detection engine. By running as a lightweight daemon (adapterd) beside your reverse proxy or workload, it translates gateway-specific protocols into a standardized, versioned HTTP inspection contract and maps core security decisions back to native gateway responses.

Architecture & Design Principles

TEXT
    NGINX / Envoy / Kubernetes Gateway
                  |
                  | auth_request / ext_authz / ext_proc
                  v
    CheeseWAF-Adapters (Go, adapterd)
                  |
                  | Versioned HTTP Inspection Contract (/api/v1/adapter/inspect)
                  v
    CheeseWAF Core Daemon (Self-hosted, Go)
                  |
                  +-- Inline Synchronous Decisions (allow / block / challenge)
                  +-- Asynchronous Telemetry / Postanalytics (/api/v1/adapter/telemetry)
  • Self-Hosted & Sidecar-First: Operates without external SaaS control planes or vendor dependencies. By default, adapterd deploys as a local loopback process (127.0.0.1:9080) directly alongside the gateway.
  • Ultra-Thin Adapter Boundary: Focuses exclusively on protocol translation and response mapping. It never duplicates detectors, AST parsers, signature tables, or management state; all security decisions remain centralized in CheeseWAF core.
  • Fail-Closed by Default: When the CheeseWAF core service is unreachable or encounters timeouts, the adapter returns HTTP 503 Service Unavailable. Traffic is never silently allowed unless explicitly configured.
  • Bounded Request Body Handling: By default, request bodies are not forwarded to the core. When explicitly enabled, body inspection is capped at a strict boundary (default 64 KB). Truncated payloads are flagged with BodyTruncated=true; if the core returns allow or times out, the adapter rejects the request with HTTP 413 Request Entity Too Large.
  • Security Credentials & Network Policy: Gateway callers authenticate using the dedicated X-CheeseWAF-Adapter-Token HTTP header (never via Authorization: Bearer), restricted to validated CIDR blocks configured in CHEESEWAF_ADAPTER_TRUSTED_PROXY_CIDRS.

Versioned Inspection Contract (v1)

The adapter communicates with the CheeseWAF core via contracts/inspection/v1:

  • Inline Inspection Endpoint: Accessible by default at /api/v1/adapter/inspect, receiving normalized client metadata, TLS fingerprints, and bounded body content within a strict latency budget (default 100ms).
  • Core Security Actions:
    • allow: Permits the request and forwards it upstream.
    • block: Terminates the request and renders a configured block page or status code.
    • challenge: Triggers client verification (such as silent JS challenge or CAPTCHA).
    • log: Permits the request while recording an audit entry (normalized to monitoring mode).
  • Asynchronous Telemetry Endpoint: Hosted at /api/v1/adapter/telemetry, receiving rate-limited, best-effort events without impacting real-time forwarding throughput.

Gateway Integration Examples

1. NGINX auth_request Configuration

Use NGINX’s ngx_http_auth_request_module to authorize incoming requests with adapterd:

NGINX
# Primary business site configuration
location / {
    auth_request /cheesewaf_auth;
    auth_request_set $waf_status $upstream_status;

    # Forward to upstream application upon successful authorization
    proxy_pass http://backend_cluster;
}

# Internal authorization subrequest endpoint
location = /cheesewaf_auth {
    internal;
    proxy_pass http://127.0.0.1:9080/v1/inspect;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-CheeseWAF-Adapter-Token "YOUR_SECURE_ADAPTER_TOKEN";
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

2. Envoy ext_authz Configuration

Configure Envoy’s external authorization HTTP filter in the filter chain:

YAML
http_filters:
  - name: envoy.filters.http.ext_authz
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
      http_service:
        server_uri:
          uri: 127.0.0.1:9080
          cluster: cheesewaf_adapter_cluster
          timeout: 0.100s
        authorization_request:
          allowed_headers:
            patterns:
              - exact: cookie
              - exact: user-agent
              - prefix: x-
          headers_to_add:
            - key: x-cheesewaf-adapter-token
              value: "YOUR_SECURE_ADAPTER_TOKEN"
      failure_mode_allow: false
      with_request_body:
        max_request_bytes: 65536
        pack_as_bytes: true

When Envoy indicates x-envoy-auth-partial-body: true, the adapter flags the body as incomplete and rejects the request with HTTP 413 unless the core explicitly blocks it, preventing large-payload truncation bypasses.

Runtime Configuration Reference

BASH
# Launch the local adapter daemon
adapterd --listen 127.0.0.1:9080 --core-url http://127.0.0.1:8080
Variable / FlagDefault ValueDescription
CHEESEWAF_ADAPTER_LISTEN / --listen127.0.0.1:9080Local network address for the adapter daemon
CHEESEWAF_CORE_URL / --core-urlRequiredAddress of the self-hosted CheeseWAF data plane or core inspection service
CHEESEWAF_CORE_INSPECT_PATH/api/v1/adapter/inspectCore inline inspection API path
CHEESEWAF_CORE_TELEMETRY_PATH/api/v1/adapter/telemetryCore telemetry reporting endpoint
CHEESEWAF_CORE_HEALTH_PATH/healthzCore health endpoint used for /readyz probe delegation
CHEESEWAF_CORE_TOKENEmptyBearer token used by adapterd to communicate with the core
CHEESEWAF_ADAPTER_TOKENEmptyDedicated token required from gateways in X-CheeseWAF-Adapter-Token
CHEESEWAF_ADAPTER_TRUSTED_PROXY_CIDRS127.0.0.1/32,::1/128Trusted CIDR list permitted to provide forwarded client IP headers
CHEESEWAF_ADAPTER_REQUEST_TIMEOUT100msMaximum execution budget for inline decisions
CHEESEWAF_ADAPTER_FAIL_MODEclosedFail mode when core is offline: closed (HTTP 503) or open (HTTP 204)
CHEESEWAF_ADAPTER_FORWARD_BODYfalseEnables bounded request body inspection
CHEESEWAF_ADAPTER_MAX_BODY_BYTES65536Maximum body capture limit (64 KB)
CHEESEWAF_ADAPTER_FORWARD_SENSITIVE_HEADERSfalsePermits forwarding credentials (Cookie/Authorization) to the core

Roadmap

  1. Streaming Protocol: Envoy ext_proc adapter for streaming inspection of large request bodies and dynamic response header mutations.
  2. Kubernetes Integration: Dedicated Kubernetes Sidecar Controller supporting automated injection and routing via Pod Annotations.
  3. Ecosystem Gateways: Native integrations for Kong, Apache APISIX, and Traefik.