Kubernetes Envoy

In this example, the Next-Gen WAF agent runs in a Docker sidecar and communicates directly with an Envoy proxy deployed on the application.

Integrating the Next-Gen WAF agent into an Envoy Proxy

You can deploy the Next-Gen WAF agent for integration with the Envoy Proxy via the External Processing (ext_proc) HTTP filter. This filter communicates with the sigsci-agent via gRPC.

Configure the sigsci-agent to run with an Envoy gRPC listener instead of the normal RPC listener. To do this, set the envoy-grpc-address agent configuration option. When set, the Envoy gRPC listener starts instead of the default RPC listener.

Set the configuration value in the sigsci-agent config file:

envoy-grpc-address = "0.0.0.0:8000"

Alternatively, set the configuration value in the sigsci-agent environment:

SIGSCI_ENVOY_GRPC_ADDRESS=0.0.0.0:8000

You can also configure the sigsci-agent with TLS enabled. To do this, set the certificate and key files in the sigsci-agent config file:

envoy-grpc-cert = "/path/to/cert.pem"
envoy-grpc-key = "/path/to/key.pem"

Alternatively, set them in the sigsci-agent environment:

SIGSCI_ENVOY_GRPC_CERT=/path/to/cert.pem
SIGSCI_ENVOY_GRPC_KEY=/path/to/key.pem

Envoy configuration

Envoy must be configured with an External Processing HTTP filter (envoy.filters.http.ext_proc) before the main handler filter to process data, such as the one shown in the example below that points at the sigsci-agent-grpc cluster.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
http_filters:
- name: envoy.filters.http.buffer
typed_config: # Maximum request body bytes buffered and sent to the sigsci-agent
"@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer
max_request_bytes: 1048576 # 1 MB body size limit
- name: envoy.filters.http.ext_proc
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
grpc_service:
envoy_grpc:
cluster_name: sigsci-agent-grpc
timeout: 0.2s
failure_mode_allow: true
message_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
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

Sample deployment

The Sample deployment configuration section contains a complete Envoy proxy deployment configuration, which you can use as a starting point for your own deployment. For the sample configuration to work, complete the following steps:

  1. Update the agent keys for your workspace by running the following command:

    $ kubectl create secret generic sigsci.test \
    --from-literal=accesskeyid=<access-key-id> \
    --from-literal=secretaccesskey=<secret-access-key>

    Be sure to replace <access-key-id> and <secret-access-key> with your agent keys.

  2. Save the Sample deployment configuration as envoy-deployment.yaml.

  3. Deploy envoy-deployment.yaml by running the following command:

    $ kubectl apply -f envoy-deployment.yaml
  4. (Optional) Set up port forwarding and test the deployment locally by running the following command:

    $ kubectl port-forward svc/envoy 10000:10000

Sample deployment configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# ConfigMap: Contains the Envoy configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-config
data:
envoy.yaml: |
node:
id: proxy-node
cluster: proxy-cluster
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
# CORS configuration at virtual host level
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
routes:
- match:
prefix: "/"
route:
cluster: edge_cluster
host_rewrite_literal: "http.edgecompute.app"
http_filters:
# CORS filter to handle cross-origin requests
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
# External processor filter calls the NGWAF agent via gRPC
- name: envoy.filters.http.ext_proc
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
grpc_service:
envoy_grpc:
cluster_name: sigsci-agent-grpc
timeout: 0.2s
failure_mode_allow: true
message_timeout: 0.2s
# Request attributes sent to the external processor
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
# Router filter (must be last)
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
# Cluster for forwarding requests to the upstream service
- name: edge_cluster
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
dns_lookup_family: V4_ONLY # Force IPv4-only DNS resolution
load_assignment:
cluster_name: edge_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: http.edgecompute.app
port_value: 443
# TLS configuration for upstream HTTPS connection
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: "http.edgecompute.app"
# Cluster used by the external processor filter to contact the NGWAF agent
- name: sigsci-agent-grpc
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
http2_protocol_options: {} # Enable HTTP/2 for gRPC communication
load_assignment:
cluster_name: sigsci-agent-grpc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
# Both containers share the same network namespace
address: 127.0.0.1
port_value: 9999
---
# Deployment: Combines the Envoy proxy and the Next‑Gen WAF Agent sidecar
apiVersion: apps/v1
kind: Deployment
metadata:
name: envoy-waf-deployment
spec:
replicas: 1
selector:
matchLabels:
app: envoy-waf
template:
metadata:
labels:
app: envoy-waf
spec:
containers:
# Envoy proxy container
- name: envoy
image: envoyproxy/envoy:v1.31-latest
args:
- "-c"
- "/etc/envoy/envoy.yaml"
- "-l"
- "debug" # Change to "trace" for even more verbosity
ports:
- containerPort: 10000
volumeMounts:
- name: envoy-config
mountPath: /etc/envoy
# Next‑Gen WAF Agent container (sigsci-agent)
- name: sigsci-agent
image: signalsciences/sigsci-agent:latest
imagePullPolicy: IfNotPresent
env:
- name: SIGSCI_ACCESSKEYID
valueFrom:
secretKeyRef:
name: sigsci.test
key: accesskeyid
- name: SIGSCI_SECRETACCESSKEY
valueFrom:
secretKeyRef:
name: sigsci.test
key: secretaccesskey
# Configure agent for Envoy external processor integration
- name: SIGSCI_ENVOY_EXTPROC_ENABLED
value: "true"
- name: SIGSCI_ENVOY_GRPC_ADDRESS
value: "localhost:9999"
- name: SIGSCI_DEBUG_LOG_VERBOSITY
value: "3"
- name: SIGSCI_SERVER_FLAVOR
value: "envoy-sidecar"
ports:
- containerPort: 9999
securityContext:
# The sigsci-agent container should run with its root filesystem read only
readOnlyRootFilesystem: true
volumeMounts:
- name: sigsci-tmp
mountPath: /sigsci/tmp
volumes:
- name: envoy-config
configMap:
name: envoy-config
# 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: {}
---
# Service: Exposes the Envoy listener on port 10000
apiVersion: v1
kind: Service
metadata:
name: envoy
spec:
selector:
app: envoy-waf
ports:
- protocol: TCP
port: 10000
targetPort: 10000