External processing extension configuration reference
Enterprise
This feature requires Consul Enterprise. Refer to the enterprise feature matrix for additional information.
This topic describes how to configure the external processing Envoy extension, which configures Envoy proxies to send request and response data to an external processing service. Refer to Delegate request and response processing to an external service for usage information.
The external processing extension applies to API gateway and sidecar proxies. You can attach it to the inbound or outbound listener of a connect-proxy, or to the inbound listener of an api-gateway.
Configuration model
The following list shows the field hierarchy, data types, and requirements for the external processing configuration. Place the configuration inside the EnvoyExtensions.Arguments field in the proxy defaults or service defaults configuration entry. Refer to the following documentation for additional information:
EnvoyExtensionsin proxy defaultsEnvoyExtensionsin service defaults- Envoy external processing documentation
Select a property name to view additional details, including default values.
Name: string | required | must be set tobuiltin/ext-procArguments: map | requiredProxyType: string | required |api-gatewayListenerType: string |inboundInsertOptions: mapLocation: stringFilterName: string
Config: map | requiredGrpcService: mapHttpService: mapStatPrefix: stringFailureModeAllow: boolean |falseRouteCacheAction: string |DEFAULT| gRPC onlyMessageTimeout: stringProcessing: mapRequest: mapHeadersMode: string |SENDBodyMode: string |SKIPTrailersMode: string |SKIPMaxBodyBytes: number
Response: mapHeadersMode: string |SKIPBodyMode: string |SKIPTrailersMode: string |SKIPMaxBodyBytes: number
Complete configuration
When each field is defined, an ext-proc configuration has the following form:
Name = "builtin/ext-proc"
Arguments = {
ProxyType = "api-gateway"
ListenerType = "inbound"
InsertOptions = {
Location = "<location in the filter chain>"
FilterName = "<filter relative to the location>"
}
Config = {
GrpcService = {
Target = {
Service = {
Name = "<processing service to send gRPC requests to>"
Namespace = "<namespace containing the processing service>"
Partition = "<partition containing the processing service>"
Port = "<named port of a multi-port processing service>"
}
URI = "<URI of the processing service>"
Timeout = "5s"
}
Authority = "<authority header to send in the gRPC request>"
}
HttpService = {
Target = {
Service = {
Name = "<processing service to send HTTP requests to>"
Namespace = "<namespace containing the processing service>"
Partition = "<partition containing the processing service>"
Port = "<named port of a multi-port processing service>"
}
URI = "<URI of the processing service>"
Timeout = "5s"
}
Path = "/<processing-request-path>"
}
StatPrefix = "<prefix that uniquely identifies this instance>"
FailureModeAllow = false
RouteCacheAction = "DEFAULT" // gRPC only
MessageTimeout = "<maximum duration to wait for a processor response>"
Processing = {
Request = {
HeadersMode = "SEND"
BodyMode = "SKIP"
TrailersMode = "SKIP"
MaxBodyBytes = <max bytes buffered when BodyMode buffers the body>
}
Response = {
HeadersMode = "SKIP"
BodyMode = "SKIP"
TrailersMode = "SKIP"
MaxBodyBytes = <max bytes buffered when BodyMode buffers the body>
}
}
}
}
Specification
This section describes the fields you can configure for the external processing extension.
Name
Specifies the name of the extension. Must be set to builtin/ext-proc.
Values
- Default: None
- This field is required.
- Data type: String value set to
builtin/ext-proc.
Arguments
Contains the global configuration for the extension.
Values
- Default: None
- This field is required.
- Data type: Map
Arguments.ProxyType
Specifies the type of Envoy proxy that this extension applies to. The extension only applies to proxies that match this type and is ignored for all other proxy types.
Values
- Default:
api-gateway - This field is required.
- Data type is one of the following string values:
api-gatewayā applies the extension to an API gateway proxy. The extension is always attached to the inbound listener.connect-proxyā applies the extension to a sidecar (service mesh) proxy. The extension can be attached to either the inbound or outbound listener, as controlled by theListenerTypefield.
Arguments.ListenerType
Specifies the type of listener the extension applies to.
| Value | Behavior |
|---|---|
inbound | Consul enables external processing for requests that other services in the mesh send to the service attached to the proxy. |
outbound | Consul enables external processing for requests that the attached proxy sends to other services in the mesh. |
any | Consul enables external processing on both the inbound and outbound listeners. |
When ProxyType is set to api-gateway, Consul always applies the extension to the inbound listener regardless of this value.
Values
Arguments.InsertOptions
Specifies options for defining the insertion point for the external processing filter in the Envoy filter chain. By default, Consul inserts the external processing filter before the envoy.filters.http.router filter.
Values
- Default: None
- Data type: Map
Arguments.InsertOptions.Location
Specifies the insertion point for the external processing filter in the Envoy filter chain. You can specify one of the following string values:
First: Inserts the filter as the first filter in the filter chain, regardless of the filter specified in theFilterNamefield.BeforeLast: Inserts the filter before the last filter in the chain, regardless of the filter specified in theFilterNamefield. This allows the filter to be inserted after all other filters and immediately before the terminal filter.AfterFirstMatch: Inserts the filter after the first filter in the chain that has a name matching the value of theFilterNamefield.AfterLastMatch: Inserts the filter after the last filter in the chain that has a name matching the value of theFilterNamefield.BeforeFirstMatch(default): Inserts the filter before the first filter in the chain that has a name matching the value of theFilterNamefield.BeforeLastMatch: Inserts the filter before the last filter in the chain that has a name matching the value of theFilterNamefield.
Values
- Default:
BeforeFirstMatch - Data type: String
Arguments.InsertOptions.FilterName
Specifies the name of an existing filter in the chain to match when inserting the external processing filter. Specifying a filter name enables you to configure an insertion point relative to the position of another filter in the chain.
Values
- Default:
envoy.filters.http.router - Data type: String
Arguments.Config
Contains the configuration settings for the extension. Configure either the GrpcService or the HttpService settings, but not both.
Values
- Default: None
- This field is required.
- Data type: Map
Arguments.Config.GrpcService
Specifies the external processing configuration for a gRPC processor. Configure the GrpcService or the HttpService settings, but not both.
A gRPC processor communicates with Envoy over a bidirectional gRPC stream and supports the full external processing lifecycle, including request and response header, body, and trailer processing.
Values
- Default: None
- Either the
GrpcServiceor theHttpServiceconfiguration is required. - Data type: Map
Arguments.Config.GrpcService.Target
Specifies the service that Envoy sends gRPC processing requests to. The Target field may contain the following fields:
Values
- Default: None
- This field is required.
- Data type: Map
Arguments.Config.GrpcService.Target.Service
Specifies the upstream external processing service. Configure this field when Envoy sends processing requests to a service within the service mesh. When you attach the extension to a connect-proxy, the service must be configured as an upstream of the service that the filter is applied to.
Configure either the Service field or the URI field, but not both.
Values
- Default: None
- This field or
URIis required. - Data type: Map
The following table describes how to configure parameters for the Service field:
| Parameter | Description | Data type | Default |
|---|---|---|---|
Name | Specifies the name of the upstream service. | String | None |
Namespace | Enterprise | String | default |
Partition | Enterprise | String | default |
Port | Specifies the name of the port to target when the upstream service exposes multiple ports. | String | None |
Arguments.Config.GrpcService.Target.URI
Specifies the URI of the external processing service. Configure this field when you must provide an explicit URI to the processing service, such as when the processing service runs on the same host or pod. When set, the value of this field must be one of localhost:<port>, 127.0.0.1:<port>, or ::1:<port>.
Configure either the URI field or the Service field, but not both.
Values
- Default: None
- This field or
Serviceis required. - Data type: String
Arguments.Config.GrpcService.Target.Timeout
Specifies the maximum duration that Envoy waits to establish the connection to the processing service.
Values
- Default:
5s - Data type: String
Arguments.Config.GrpcService.Authority
Specifies the authority header to send in the gRPC request. When this field is not set, Consul sets the authority header to the cluster name.
Values
- Default: Cluster name
- Data type: String
Arguments.Config.HttpService
Specifies the external processing configuration for an HTTP processor. Configure the HttpService or the GrpcService settings, but not both.
An HTTP processor communicates with Envoy over the HTTP side stream. It supports request header processing only.
Values
- Default: None
- Either the
HttpServiceor theGrpcServiceconfiguration is required. - Data type: Map
Arguments.Config.HttpService.Target
Specifies the service that Envoy sends HTTP processing requests to. The Target field may contain the following fields:
Values
- Default: None
- This field is required.
- Data type: Map
Arguments.Config.HttpService.Target.Service
Specifies the upstream external processing service. Configure this field when Envoy sends processing requests to a service within the service mesh. When you attach the extension to a connect-proxy, the service must be configured as an upstream of the service that the filter is applied to.
Configure either the Service field or the URI field, but not both.
Values
- Default: None
- This field or
URIis required. - Data type: Map
The following table describes how to configure parameters for the Service field:
| Parameter | Description | Data type | Default |
|---|---|---|---|
Name | Specifies the name of the upstream service. | String | None |
Namespace | Enterprise | String | default |
Partition | Enterprise | String | default |
Port | Specifies the name of the port to target when the upstream service exposes multiple ports. | String | None |
Arguments.Config.HttpService.Target.URI
Specifies the URI of the external processing service. Configure this field when you must provide an explicit URI to the processing service, such as when the processing service runs on the same host or pod. When set, the value of this field must be one of localhost:<port>, 127.0.0.1:<port>, or ::1:<port>.
Configure either the URI field or the Service field, but not both.
Values
- Default: None
- This field or
Serviceis required. - Data type: String
Arguments.Config.HttpService.Target.Timeout
Specifies the maximum duration that Envoy waits to establish the connection to the processing service.
Values
- Default:
5s - Data type: String
Arguments.Config.HttpService.Path
Specifies the HTTP path that Envoy sends processing requests to on the external processing service. You must include the leading forward slash (/). To avoid a processing loop, Consul disables external processing on routes that match this path.
Values
- Default:
/ - Data type: String
Arguments.Config.StatPrefix
Specifies a prefix that uniquely identifies this external processing instance. Consul uses the prefix to derive a unique Envoy filter name in the form envoy.filters.http.ext_proc/<StatPrefix> and to namespace the statistics that the filter emits. When you omit the prefix, Consul uses the unsuffixed filter name envoy.filters.http.ext_proc.
When you configure two or more external processing instances on the same filter chain, you must set a unique StatPrefix for each instance.
Values
- Default: None
- Data type: String
Arguments.Config.FailureModeAllow
Controls how Envoy handles requests when the external processing service is unreachable or returns an error. When set to false, Envoy rejects the request. When set to true, Envoy allows the request to proceed.
Values
- Default:
false - Data type: Boolean
Arguments.Config.RouteCacheAction
Controls how Envoy handles the route cache after the processing service returns response headers. This field is only effective for gRPC processors. You can specify one of the following string values:
DEFAULT: Envoy clears the route cache when the processing service modifies a header that affects routing.CLEAR: Envoy always clears the route cache so that header changes made by the processing service affect routing decisions.RETAIN: Envoy retains the route cache and ignores header changes that would otherwise affect routing.
Values
- Default:
DEFAULT - Data type: String
Arguments.Config.MessageTimeout
Specifies the maximum duration that Envoy waits for a response from the processing service for each message. Specify the value as a duration string, such as 200ms. When you omit this field, Envoy applies its built-in default of no timeout. Refer to the Envoy message_timeout documentation for details.
Values
- Default: No timeout (Envoy built-in default)
- Data type: String
Arguments.Config.Processing
Specifies which phases of the request and response lifecycle Envoy sends to the processing service. When you omit this field, Envoy sends request headers only (equivalent to setting Request.HeadersMode = SEND).
Values
- Default: Sends request headers only (
Request.HeadersMode = SEND; all other phases skipped) - Data type: Map
Arguments.Config.Processing.Request
Specifies the processing modes that Envoy applies to the request direction.
Values
- Default: None
- Data type: Map
The following table describes the parameters that you can configure in the Request field:
| Parameter | Description | Data type | Default |
|---|---|---|---|
HeadersMode | Controls whether Envoy sends request headers to the processing service. Set to SEND or SKIP. | String | SEND |
BodyMode | Controls whether and how Envoy sends the request body to the processing service. Set to SKIP, BUFFERED, BUFFERED_PARTIAL, or STREAMED. | String | SKIP |
TrailersMode | Controls whether Envoy sends request trailers to the processing service. Set to SEND or SKIP. | String | SKIP |
MaxBodyBytes | Specifies the maximum number of body bytes Envoy buffers when BodyMode is BUFFERED or BUFFERED_PARTIAL. | Integer | None |
Arguments.Config.Processing.Response
Specifies the processing modes that Envoy applies to the response direction.
Values
- Default: None
- Data type: Map
The following table describes the parameters that you can configure in the Response field:
| Parameter | Description | Data type | Default |
|---|---|---|---|
HeadersMode | Controls whether Envoy sends response headers to the processing service. Set to SEND or SKIP. | String | SKIP |
BodyMode | Controls whether and how Envoy sends the response body to the processing service. Set to SKIP, BUFFERED, BUFFERED_PARTIAL, or STREAMED. | String | SKIP |
TrailersMode | Controls whether Envoy sends response trailers to the processing service. Set to SEND or SKIP. | String | SKIP |
MaxBodyBytes | Specifies the maximum number of body bytes Envoy buffers when BodyMode is BUFFERED or BUFFERED_PARTIAL. | Integer | None |
Examples
The following examples demonstrate common configuration patterns for specific use cases.
Process gateway requests with a gRPC service
The following service defaults configuration entry attaches an ext-proc extension to the inbound listener of an api-gateway. The configuration directs the gateway to send requests to the ext-proc service over gRPC and to clear the route cache so that header changes affect routing:
api-gateway-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Arguments = {
ProxyType = "api-gateway"
ListenerType = "inbound"
Config = {
StatPrefix = "route-decider"
RouteCacheAction = "CLEAR"
GrpcService = {
Target = {
Service = {
Name = "ext-proc"
}
}
}
}
}
}
]
Process sidecar requests with a gRPC service
The following service defaults configuration entry attaches an ext-proc extension to the inbound listener of the service-e sidecar proxy. When another mesh service sends a request to service-e, the proxy sends the request to the ext-proc-connect-proxy service over gRPC:
service-e-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "service-e"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Arguments = {
ProxyType = "connect-proxy"
ListenerType = "inbound"
Config = {
RouteCacheAction = "CLEAR"
GrpcService = {
Target = {
Service = {
Name = "ext-proc-connect-proxy"
}
}
}
}
}
}
]
Process sidecar requests with a local HTTP service
The following service defaults configuration entry attaches an ext-proc extension to the inbound listener of the service-e1 sidecar proxy. The processing service runs as a sidecar in the same pod, so the extension targets a local URI instead of a mesh service:
service-e1-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "service-e1"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Arguments = {
ProxyType = "connect-proxy"
ListenerType = "inbound"
Config = {
RouteCacheAction = "CLEAR"
HttpService = {
Target = {
URI = "127.0.0.1:9000"
}
Path = "/decide"
}
}
}
}
]
Route traffic with a ServiceRouter based on ext-proc headers
The following examples demonstrate how to use the ext-proc extension together with a ServiceRouter to perform header-based routing. The ext-proc service injects a custom header during request processing, and the ServiceRouter uses that header to direct traffic to different upstream services.
In this pattern, service-c runs ext-proc on its outbound listener so that the header is injected before the request leaves the sidecar. The ServiceRouter for service-d2 then matches on the header value to select the correct destination.
The following configuration attaches an ext-proc extension to the outbound listener of the service-c sidecar proxy. When service-c sends a request to service-d2, the sidecar forwards the request to ext-proc-grpc first, which injects the x-cell header before the request is routed:
service-c-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "service-c"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Required = true
Arguments = {
ProxyType = "connect-proxy"
ListenerType = "outbound"
Config = {
GrpcService = {
Target = {
Service = {
Name = "ext-proc-grpc"
}
}
}
}
}
}
]
The following configuration for service-d2 routes traffic based on the x-cell header value. Requests with x-cell: C are forwarded to service-d1, while requests with x-cell: D are forwarded to service-d2:
service-d2-service-router.hcl
Kind = "service-router"
Name = "service-d2"
Routes = [
{
Match = {
HTTP = {
Header = [
{
Name = "x-cell"
Exact = "C"
}
]
}
}
Destination = {
Service = "service-d1"
}
},
{
Match = {
HTTP = {
Header = [
{
Name = "x-cell"
Exact = "D"
}
]
}
}
Destination = {
Service = "service-d2"
}
}
]
Route API gateway traffic with ext-proc and a named service port
The following example shows how to attach ext-proc to an API gateway when the processing service must be reached by an explicit port. Unlike a connect-proxy sidecar, the API gateway Envoy does not pre-build outbound clusters for upstream services. You must set the Port field so that Consul can construct the correct xDS cluster address. Without a port, Consul silently skips the filter and traffic passes through without any header injection.
The following configuration attaches an ext-proc extension to the inbound listener of the api-gateway and uses RouteCacheAction: CLEAR so that any headers injected by the processing service affect routing decisions:
api-gateway-named-port-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Required = true
Arguments = {
ProxyType = "api-gateway"
ListenerType = "inbound"
Config = {
RouteCacheAction = "CLEAR"
GrpcService = {
Target = {
Service = {
Name = "ext-proc-grpc"
Port = "50051"
}
}
}
}
}
}
]
Process request and response bodies
The following service defaults configuration entry attaches an ext-proc extension that sends request headers and the buffered request body to the processing service, as well as the response headers:
api-gateway-body-processor-ext-proc-service-defaults.hcl
Kind = "service-defaults"
Name = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
{
Name = "builtin/ext-proc"
Arguments = {
ProxyType = "api-gateway"
ListenerType = "inbound"
Config = {
StatPrefix = "body-processor"
GrpcService = {
Target = {
Service = {
Name = "ext-proc"
}
}
}
Processing = {
Request = {
HeadersMode = "SEND"
BodyMode = "BUFFERED"
MaxBodyBytes = 8192
}
Response = {
HeadersMode = "SEND"
}
}
}
}
}
]