Kubernetes Istio
- English
- 日本語
In this example, the Next-Gen WAF agent runs in a Docker sidecar and integrates directly with an Istio service mesh deployed on the application. In this configuration, you can configure the Next-Gen WAF to inspect east/west (service-to-service) web requests along with the traditional north/south (client to server) requests.
Integrating the Next-Gen WAF agent
Refer to Agent container image integration
Integrating the Next-Gen WAF agent using EnvoyFilter
Istio uses the Envoy proxy as its data plane. As a result, you can use the Next-Gen WAF agent in gRPC mode the same way you would with a generic Envoy deployment. Installing and configuring the Next-Gen WAF agent is similar to a generic Envoy deployment, except Istio automatically deploys the Envoy proxy as a sidecar. You then configure Envoy using Istio's EnvoyFilter.
To add Next-Gen WAF support to an Istio based application deployment, you will need to:
- Add the
sigsci-agentcontainer to the pod, configured in Envoy gRPC listener mode. - Add an
emptyDir{}volume as a place for thesigsci-agentto write temporary data. - Add an Istio
EnvoyFilterfor the app to allow the required Envoy configuration to be injected into the generatedistio-proxyconfig.
Add the Next-Gen WAF agent as an Envoy gRPC service
123456789101112131415161718192021222324252627282930313233343536373839... containers: - name: sigsci-agent image: signalsciences/sigsci-agent:latest imagePullPolicy: IfNotPresent env: - name: SIGSCI_ACCESSKEYID valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: accesskeyid - name: SIGSCI_SECRETACCESSKEY valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: secretaccesskey - name: SIGSCI_ENVOY_EXTPROC_ENABLED value: "true" # Configure the agent to use envoy gRPC on port 9999 - name: SIGSCI_ENVOY_GRPC_ADDRESS value: localhost:9999 # Comment out debug logging as appropriate - name: SIGSCI_DEBUG_LOG_VERBOSITY value: "3" - name: SIGSCI_DEBUG_LOG_WEB_INPUTS value: "2" - name: SIGSCI_DEBUG_LOG_WEB_OUTPUTS value: "2" - name: SIGSCI_DEBUG_LOG_UPLOADS value: "2" - name: SIGSCI_SERVER_FLAVOR value: "istio" ports: - containerPort: 9999 securityContext: # The sigsci-agent container should run with its root filesystem read only readOnlyRootFilesystem: trueAdding the Next-Gen WAF agent temp volume definition to the deployment
The agent temp volume needs to be defined for use by the other containers in the pod using the builtin emptyDir: {} volume type:
... volumes: # Define a volume where sigsci-agent will write temp data and share the socket file, # which is required with the root filesystem is mounted read only - name: sigsci-tmp emptyDir: {}Adding the Istio EnvoyFilter object to inject the required Envoy config into the Istio proxy
Istio's EnvoyFilter object is a feature rich way of customizing the Envoy configuration for the istio-proxy.
Example example-httpbin-sigsci_envoyfilter.yaml:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174apiVersion: v1kind: ServiceAccountmetadata: name: httpbin---apiVersion: v1kind: Servicemetadata: name: httpbin labels: app: httpbin service: httpbinspec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata: name: httpbin labels: app: httpbinspec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80 - name: sigsci-agent image: signalsciences/sigsci-agent:latest imagePullPolicy: IfNotPresent env: - name: SIGSCI_ACCESSKEYID valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: accesskeyid - name: SIGSCI_SECRETACCESSKEY valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: secretaccesskey - name: SIGSCI_ENVOY_EXTPROC_ENABLED value: "true" # Configure the agent to use envoy gRPC on port 9999 - name: SIGSCI_ENVOY_GRPC_ADDRESS value: localhost:9999 - name: SIGSCI_DEBUG_LOG_VERBOSITY value: "0" - name: SIGSCI_DEBUG_LOG_WEB_INPUTS value: "0" - name: SIGSCI_DEBUG_LOG_WEB_OUTPUTS value: "0" - name: SIGSCI_DEBUG_LOG_UPLOADS value: "0" - name: SIGSCI_SERVER_FLAVOR value: "istio" ports: - containerPort: 9999 securityContext: # The sigsci-agent container should run with its root filesystem read only readOnlyRootFilesystem: true volumes: # Define a volume where sigsci-agent will write temp data and share the socket file, # which is required with the root filesystem is mounted read only - name: sigsci-tmp emptyDir: {}---apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: httpbin-gatewayspec: gatewayClassName: istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same---apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: httpbinspec: parentRefs: - name: httpbin-gateway rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: httpbin port: 8000---apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: httpbin namespace: defaultspec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: name: virtualInbound filterChain: filter: name: envoy.filters.network.http_connection_manager patch: operation: INSERT_FIRST value: name: envoy.filters.http.ext_proc typed_config: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor failure_mode_allow: true message_timeout: 0.2s grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc timeout: 0.2s request_attributes: - "connection.tls_version" - "request.host" - "request.path" - "request.scheme" - "source.address" processing_mode: request_header_mode: SEND response_header_mode: SEND request_body_mode: BUFFERED response_body_mode: NONE request_trailer_mode: SKIP response_trailer_mode: SKIP - applyTo: CLUSTER patch: operation: ADD value: name: sigsci-agent-grpc type: STRICT_DNS connect_timeout: 0.5s http2_protocol_options: {} load_assignment: cluster_name: sigsci-agent-grpc endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 9999To use this example,
- Follow Istio's getting started guide to install the default profile, add a namespace label to instruct Istio to automatically inject Envoy sidecar proxies, and Install the Gateway API CRDs.
The application can then be deployed as you normally would with Istio. For example:
$ kubectl apply -f example-httpbin-sigsci_envoyfilter.yamlserviceaccount/httpbin createdservice/httpbin createddeployment.apps/httpbin createdgateway.gateway.networking.k8s.io/httpbin-gateway created$ kubectl get podsNAME READY STATUS RESTARTS AGEhttpbin-d9b4c94bb-h4vfk 3/3 Running 0 70shttpbin-gateway-istio-54494c698d-vgpvp 1/1 Running 0 68s$ kubectl get pod httpbin-d9b4c94bb-h4vfk -o jsonpath='{.spec.containers[*].name}'httpbin sigsci-agent$ kubectl logs httpbin-d9b4c94bb-h4vfk sigsci-agent | head2026/06/29 20:41:29.977416 Signal Sciences Agent 4.79.0 starting as user sigsci with PID 1, Max open files=1073741816, Max data size=unlimited, Max address space=unlimited, Max stack size=83886082026/06/29 20:41:29.978372 Shared Cache Dir: /sigsci/tmp/cache2026/06/29 20:41:29.978375 Agent Cache Dir: /sigsci/tmp/cache/agent_httpbin-d9b4c94bb-h4vfk2026/06/29 20:41:29.979280 =====================================================2026/06/29 20:41:29.979282 Agent: httpbin-d9b4c94bb-h4vfk2026/06/29 20:41:29.979284 System: alpine 3.24.0 (linux 6.17.0-1025-oem)2026/06/29 20:41:29.979284 Memory: 38.903G / 58.501G RAM available2026/06/29 20:41:29.979285 CPU: 12 MaxProcs / 24 CPU cores available2026/06/29 20:41:29.979286 gRPC: localhost:99992026/06/29 20:41:29.979286 =====================================================Integrating the Next-Gen WAF agent using external authorization
WARNING: The following integration method is considered legacy and preference would be to integrate using EnvoyFilter
As of Istio v1.9, support has been added to setup an authorization policy that delegates access control to an external authorization system.
The snippets below follow Istio's example and enhance the process to replace the example ext-authz service with the Next-Gen WAF agent. Refer to the Istio documentation for initial namespace and test workloads, as those are referenced in the snippets below. All files are applied to the 'foo' namespace unless otherwise indicated.
Deploy the external authorizer
Assumes the secrets have been applied.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657apiVersion: v1kind: Servicemetadata: name: sigsci-agent labels: app: sigsci-agentspec: ports: - name: grpc port: 9999 targetPort: 9999 selector: app: sigsci-agent---apiVersion: apps/v1kind: Deploymentmetadata: name: sigsci-agentspec: replicas: 1 selector: matchLabels: app: sigsci-agent template: metadata: labels: app: sigsci-agent spec: containers: - name: sigsci-agent image: signalsciences/sigsci-agent:latest imagePullPolicy: IfNotPresent # Configure the agent to use Envoy gRPC on port 9999 env: - name: SIGSCI_ACCESSKEYID valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: accesskeyid - name: SIGSCI_SECRETACCESSKEY valueFrom: secretKeyRef: # This secret needs added (see docs on sigsci secrets) name: sigsci-agent-accesskey key: secretaccesskey # Configure the Envoy to expect response data (if using a gRPC access log config for Envoy) - name: SIGSCI_ENVOY_EXPECT_RESPONSE_DATA value: "1" - name: SIGSCI_ENVOY_GRPC_ADDRESS value: :9999 ports: - containerPort: 9999 securityContext: # The sigsci-agent container should run with its root filesystem read only readOnlyRootFilesystem: true---Verify the Agent is running.
$ kubectl logs "$(kubectl get pod -l app=sigsci-agent -n foo -o jsonpath={.items..metadata.name})" -n foo -c sigsci-agentDefine the external authorizer
Edit the mesh config with the following command and add the extension provide definitions.
$ kubectl edit configmap istio -n istio-system123456789101112131415161718192021222324252627282930data: mesh: |- # Add the following content to define the external authorizers. extensionProviders: - name: "sigsci-agent-ext-authz" envoyExtAuthzGrpc: service: "sigsci-agent.foo.svc.cluster.local" port: "9999" timeout: 0.2s failOpen: true includeRequestBodyInCheck: packAsBytes: true # use `allowPartialMessage: false` if you want to inspect larger payloads allowPartialMessage: true maxRequestBytes: 8192 - name: "sigsci-agent-access-log" envoyHttpAls: service: "sigsci-agent.foo.svc.cluster.local" port: "9999" additionalRequestHeadersToLog: - "x-sigsci-request-id" - "x-sigsci-waf-response" - "accept" - "content-type" - "content-length" additionalResponseHeadersToLog: - "date" - "server" - "content-type" - "content-length"Enable with external authorization
Enable the external authorization and apply logging.
1234567891011121314151617apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata: name: ext-authzspec: selector: matchLabels: app: httpbin action: CUSTOM provider: # The provider name must match the extension provider defined in the mesh config. name: sigsci-agent-ext-authz rules: # The rules specify when to trigger the external authorizer. - to: - operation: paths: ["/headers"]12345678910# kubectl apply -f logging.yamlapiVersion: telemetry.istio.io/v1alpha1kind: Telemetrymetadata: name: mesh-default namespace: istio-systemspec: accessLogging: - providers: - name: sigsci-agent-access-log# In another terminal curl the httpbin app:$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl -v "http://httpbin.foo:8000/headers" -s
# tail the logs$ kubectl logs -f "$(kubectl get pod -l app=sigsci-agent -n foo -o jsonpath={.items..metadata.name})" -n foo -c sigsci-agent