About external processing
Envoy offers multiple filters that you can use to manage, monitor, and secure traffic to your apps. Although Envoy is extensible via C++ and WebAssembly modules, it might not be practical to implement these extensions for all of your apps. You might also have very specific requirements for how to process a request or response to allow traffic routing between different types of apps, such as adding specific headers to new and legacy apps.
With external processing, you can implement an external processing server that can read and modify all aspects of an HTTP request or response, such as headers, body, and trailers. This gives you the flexibility to apply your requirements to all types of apps, without the need to run WebAssembly or other custom scripts.
External processing is an Enterprise-only feature.
How it works
The following diagram shows an example for how request header manipulation works when an external processing server is used.
- The downstream service sends a request with headers to the Envoy gateway.
- The gateway extracts the header information and sends it to the external processing server.
- The external processing server modifies, adds, or removes the request headers.
- The modified request headers are sent back to the gateway.
- The modified headers are added to the request.
- The request is forwarded to the upstream application.
ExtProc server considerations
The ExtProc server is a gRPC interface that must be able to respond to events in the lifecycle of an HTTP request. When the ExtProc filter is enabled in Gloo Gateway and a request or response is received on the gateway, the filter communicates with the ExtProc server by using bidirectional gRPC streams.
To implement your own ExtProc server, make sure that you follow Envoy’s technical specification for an external processor. You can also follow the Header manipulation example to try out ExtProc in Gloo Gateway with a sample ExtProc server.
In Gloo Gateway version 1.17.0, the Gloo Gateway extProc filter implementation was changed to comply with the latest extProc implementation in Envoy. Previously, request and response attributes were included only in a header processing request, and were therefore sent to the extProc server only when request header processing messages were configured to be sent. Starting in Gloo Gateway version 1.17.0, the Gloo extProc filter sends request and response attributes as part of the top-level processing request. That way, attributes can be processed on the first processing request regardless of its type.
If you implemented your extProc server to expect request and response attributes as part of the HTTP header processing request, you must change this implementation to read attributes from the top-level processing request instead.
For more information, see the extProc proto definition in Envoy.
ExtProc filter variants
Gloo Gateway supports three ExtProc filter variants that run at different positions in the Envoy filter chain. You can configure one or more variants simultaneously to process a request at multiple stages. For an overview of the filters in the Envoy filter chain, see Filter flow description.
| Field | Position in filter chain | Notes |
|---|---|---|
extProcEarly |
Early stage | Stage is configurable via the filterStage field. For example, choose FaultStage to execute the variant before or after the fault injection stage, which is the first filter in the Envoy filter chain. Depending on your filter stage setting, this variant might be executed before or after the extProc variant. |
extProc |
Middle stage | Stage is configurable via the filterStage field. For example, choose AuthNStage to execute the variant before or after the external authentication stage. Depending on your filter stage setting, this variant might be executed before or after the extProcEarly variant. |
extProcLate |
Final filter before a request leaves Envoy; first filter when a response enters Envoy | You must provide a filterStage setting with supported values. However, this setting is ignored as this variant is always executed as part of the upstream_http_filter. This filter is part of the Router phase, which is the last filter in the Envoy filter chain. |
Using multiple variants lets you observe what Envoy modifies between stages. For example, you can configure extProcEarly and extProcLate to log a request as it enters the filter chain and again just before it leaves Envoy, and compare the two to identify changes that Envoy made in between.
Enable ExtProc in Gloo Gateway
You can enable any of the extProc filter variants globally for all requests and responses that the gateway processes by using the Settings custom resource. Alternatively, you can enable extProc for a specific gateway listener, virtual host, or route.
The following table summarizes which fields are available at each configuration level.
| Configuration level | Available fields |
|---|---|
| Settings (global) | extProcEarly, extProc, extProcLate |
| HttpListenerOptions | extProcEarly / disableExtProcEarly, extProc / disableExtProc, extProcLate / disableExtProcLate |
| VirtualHostOptions | extProcEarly, extProc, extProcLate |
| RouteOptions | extProcEarly, extProc, extProcLate |
Settings defined at a lower level (listener, virtual host, or route) override the global Settings defaults via a shallow merge.
Global settings configuration
The following example shows how to configure all three extProc filter variants in the default Settings resource.
extProcEarly:
grpcService:
extProcServerRef:
name: early-ext-proc-grpc-4444
namespace: gloo-system
filterStage:
stage: AuthNStage
predicate: Before
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SKIP
extProc:
grpcService:
extProcServerRef:
name: default-ext-proc-grpc-4444
namespace: gloo-system
filterStage:
stage: AuthZStage
predicate: After
failureModeAllow: false
allowModeOverride: false
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SKIP
extProcLate:
grpcService:
extProcServerRef:
name: late-ext-proc-grpc-4444
namespace: gloo-system
# Filter stage must be set, but has no effect. Variant is always executed in the upstream_http_filter.
filterStage:
stage: AuthZStage
predicate: After
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SEND
The filterStage field has no effect on extProcLate. The late filter always runs as the final filter before a request leaves Envoy and as the first filter when a response enters Envoy.
Disable a variant at the listener level
To disable a specific extProc variant for a gateway listener while leaving other variants enabled globally, create an HttpListenerOption resource and disable the specific variant in the options section.
For example, you might enable all three variants globally to log requests as they enter (extProcEarly) and exit (extProcLate) the filter chain for full observability. However, for a listener that handles high-throughput internal traffic where the extra processing stages add unnecessary latency, you can disable extProcEarly and extProcLate for that listener while keeping extProc active for authentication or header manipulation.
The following example disables extProcEarly and extProcLate for the HTTP listener on the gateway-proxy, while leaving the extProc variant active.
apiVersion: gateway.solo.io/v1
kind: HttpListenerOption
metadata:
name: disable-extproc-variants
namespace: gloo-system
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-proxy
namespace: gloo-system
sectionName: http
options:
disableExtProcEarly: true
disableExtProcLate: true
Override global settings at route level
You can override the global extProc settings, such as the processing mode or request and response attributes for a route by using the overrides fields as shown in the following example.
kubectl apply -f- <<EOF
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: vs
namespace: gloo-system
spec:
virtualHost:
domains:
- '*'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: default-httpbin-8000
namespace: gloo-system
options:
extProcEarly:
overrides:
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SEND
extProcLate:
overrides:
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SEND
EOF