Introduction

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 gRPC processing server that can read and modify all aspects of an HTTP request or response, such as headers, body, and trailers, and add that server to the Envoy filter chain by using the Envoy external processing (ExtProc) filter. The external service can manipulate headers, body, and trailers of a request or response before it is forwarded to an upstream or downstream service. The request or response can also be terminated at any given time.

With this approach, you have the flexibility to apply your requirements to all types of apps, without the need to run WebAssembly or other custom scripts.

How it works

The following diagram shows an example for how request header manipulation works when an external processing server is used.

Request header manipulation with external processing
Request header manipulation with external processing

  1. The downstream service sends a request with headers to the Envoy gateway.
  2. The gateway extracts the header information and sends it to the external processing server.
  3. The external processing server modifies, adds, or removes the request headers.
  4. The modified request headers are sent back to the gateway.
  5. The modified headers are added to the request.
  6. 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.

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.

FieldPosition in filter chainNotes
extProcEarlyEarly stageStage 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.
extProcMiddle stageStage 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.
extProcLateFinal filter before a request leaves Envoy; first filter when a response enters EnvoyYou 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.

For an example, see Use multiple extProc filter variants.

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 or route.

The following table summarizes which fields are available at each configuration level.

Configuration levelAvailable fields
Settings (global)extProcEarly, extProc, extProcLate
HttpListenerOptionsextProcEarly / disableExtProcEarly, extProc / disableExtProc, extProcLate / disableExtProcLate
RouteOptionsextProcEarly, extProc, extProcLate

Settings defined at a lower level (listener 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.

  1. Edit the default Settings resource.

      kubectl edit settings default -n gloo-system
      
  2. Add the following values to the spec section.

      extProcEarly:
      grpcService:
        extProcServerRef:
          name: early-ext-proc-grpc
          namespace: gloo-system
      filterStage:
        stage: AuthNStage
        predicate: Before
      processingMode:
        requestHeaderMode: SEND
        responseHeaderMode: SKIP
    extProc:
      grpcService:
        extProcServerRef:
          name: ext-proc-grpc
          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
          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
      
    SettingDescription
    allowModeOverrideAllow the extProc server to override the processing mode settings that you set. Default value is false.
    failureModeAllowAllow the extProc server to continue when an error is detected during external processing. If set to true, the extProc server continues. If set to false, external processing is stopped and an error is returned to the Envoy proxy.
    filterStage.predicateHow to apply the filter relative to filterStage.stage. Applies to extProcEarly and extProc. Has no effect on extProcLate, which always runs as the final filter before a request leaves Envoy.
    filterStage.stageThe stage in the filter chain where you want to enable external processing. Applies to extProcEarly and extProc.
    grpcService.extProcServerRefThe name and namespace of the Upstream resource that represents your external processing server.
    processingMode.requestHeaderModeSend (SEND) or skip sending (SKIP) request header information to the extProc server.
    processingMode.responseHeaderModeSend (SEND) or skip sending (SKIP) response header information to the extProc server.

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.

  kubectl apply -f- <<EOF
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: http
    namespace: gloo-system
    sectionName: http
  options:
    disableExtProcEarly: true
    disableExtProcLate: true
EOF
  

Override global settings at route level

You can override the global extProc settings for a specific route by using a RouteOption resource. The following example overrides the processing mode for extProcEarly and extProcLate on a specific route.

  kubectl apply -f- <<EOF
apiVersion: gateway.solo.io/v1
kind: RouteOption
metadata:
  name: extproc-override
  namespace: httpbin
spec:
  options:
    extProcEarly:
      overrides:
        processingMode:
          requestHeaderMode: SEND
          responseHeaderMode: SEND
    extProcLate:
      overrides:
        processingMode:
          requestHeaderMode: SEND
          responseHeaderMode: SEND
EOF
  

For an example, see Overwrite gateway settings with RouteOptions.