Skip to content

External processing

HTTP filter that streams headers and bodies to an external gRPC processor, overridable per route.

AttachmentType URL (@type)Per-route overrideBuild feature
HTTP filter chain (http_filters)type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessorYes — envoy.extensions.filters.http.ext_proc.v3.ExtProcPerRoute, or envoy.config.route.v3.FilterConfigNone

What it does

External processing (ext_proc) hands each request and response to a gRPC service you run, which can mutate headers and bodies or answer immediately on Arion's behalf. processing_mode decides what is sent — headers, bodies, trailers, in streamed or buffered form — so the processor sees only what it needs. It is the extension point for logic that lives outside the proxy; for in-process extension see Wasm filters.

Minimal configuration

From arion-runtime-ext_proc.yaml; the fragment is an entry in http_filters, before the router. The target cluster must speak HTTP/2:

- name: ext_proc
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
    failure_mode_allow: false
    message_timeout: 5s
    processing_mode:
      request_header_mode: "SEND"
      response_header_mode: "SKIP"
    grpc_service:
      envoy_grpc:
        cluster_name: ext_proc_server

Fields

FieldTypeRequiredDefaultDescription
grpc_serviceobjectYes—Processor target: envoy_grpc (cluster_name, optional max_receive_message_length) or google_grpc (target_uri), plus an optional timeout.
failure_mode_allowboolNofalseContinue when the processor is unreachable or errors. When false, processor message timeouts return 504 and processor or stream errors return 500.
processing_modeobjectNoheaders onlyPer-phase modes, below.
message_timeoutdurationNo200msHow long to wait for the processor's reply to each message.
max_message_timeoutdurationNounsetUpper bound the processor may raise the timeout to.
mutation_rulesobjectNounsetRestrict header mutations with allow_all_routing, allow_envoy, disallow_system, disallow_all, allow_expression, disallow_expression and disallow_is_error. Omitting the object applies no mutation-rule restrictions.
forward_rulesobjectNoallallowed_headers / disallowed_headers matcher lists limiting which headers are sent to the processor.
allow_mode_overrideboolNofalseLet the processor change the processing mode mid-stream.
allowed_override_modeslistNoemptyProcessing modes the processor may switch to.
route_cache_actionenumNoDEFAULTDEFAULT, CLEAR or RETAIN the route after header mutations.
send_body_without_waiting_for_header_responseboolNofalseStream body chunks without waiting for the header reply.
observability_modeboolNofalseFire-and-forget: send messages but never wait for answers.
disable_immediate_responseboolNofalseIgnore immediate_response messages from the processor.
deferred_close_timeoutdurationNounsetGrace period before closing the processor stream.
metadata_optionsobjectNounsetLimited support for forwarding_namespaces.untyped; include envoy.lb to report the served endpoint with response headers.

http_service, filter_metadata, request_attributes, response_attributes and status_on_error are unsupported and refused at startup.

Header mutations

Omitting mutation_rules allows the processor to modify supported headers without mutation-rule restrictions. With mutation_rules: {}, the default rules block changes to host, :authority, :scheme, :method and x-envoy- headers. Other supported pseudo-headers remain allowed unless disallow_system is enabled; allow_all_routing, allow_envoy and the expression fields adjust these restrictions.

For set_headers, leaving both append and append_action unset adds or replaces the header. append: true appends instead; an explicit append takes precedence over append_action.

Processing modes

request_header_mode / response_header_mode and the trailer modes take DEFAULT, SEND or SKIP. request_body_mode / response_body_mode take NONE, STREAMED, BUFFERED, BUFFERED_PARTIAL or FULL_DUPLEX_STREAMED.

For a processor that waits for the complete request before answering its headers, use FULL_DUPLEX_STREAMED with send_body_without_waiting_for_header_response: true. This lets request body messages reach the processor without waiting for its header reply.

Metadata forwarding

metadata_options.forwarding_namespaces.untyped: [envoy.lb] enables served-endpoint feedback. With response-header processing enabled, a cluster using the OverrideHost load-balancing policy reports the actual served endpoint in ProcessingRequest.metadata_context.filter_metadata["envoy.lb"]["x-gateway-destination-endpoint-served"], including fallback selections. This is processor metadata, not an HTTP response header.

Other untyped namespace names are accepted but do not enable arbitrary metadata forwarding. Nonempty forwarding_namespaces.typed, receiving_namespaces and cluster_metadata_forwarding_namespaces are rejected; empty receiving or cluster namespace objects are accepted. metadata_options cannot be set in per-route overrides.

Per-route override

Routes adjust the filter through typed_per_filter_config keyed by its chain name. The override type is ExtProcPerRoute: either disabled: true, or overrides carrying a different processing_mode, grpc_service or failure_mode_allow for that route. These settings work with both inline route_config and routes delivered over RDS. Per-route settings retain the filter's metadata forwarding configuration.

Ordering and interactions

The processor sees requests as earlier filters left them and can still short-circuit with an immediate response; place ext_proc before the router and after authentication unless the processor itself does the authenticating.

See the AI Inference Gateway overview and inference routing guide for endpoint selection through ext_proc.

Continue

Start typing to search the site.

↑ ↓ to move Enter to open Esc to close