envoyproxy / envoyproxy/gateway

Use Envoy `filter_chain` filter for native per-route HTTP filters

Open
#9,208 1 comment 0 reactions 0 assignees View on GitHub
kind/decision kind/enhancement stale
Dominant language
Go
Stars
3k
Forks
864
Avg merge
2d 2h
Merged PRs (30d)
140

Description

*Description*:
Envoy added `envoy.filters.http.filter_chain` in envoyproxy/envoy#42912. This filter lets Envoy install a wrapper in the HCM HTTP filter chain and select an inline sub-chain from route `typed_per_filter_config`.

Envoy Gateway should evaluate using this as a native mechanism for route-scoped HTTP filter features.

## Motivation

Many Envoy Gateway features are logically route-scoped but currently require listener/HCM-level filter-chain changes. Using Envoy’s `filter_chain` wrapper could let EG keep the listener filter chain stable while changing only route configuration.

Benefits:

- Less listener churn.
- Smaller xDS diffs for route-scoped policy changes.
- Cleaner modeling for per-route HTTP filter behavior.

## Example

Listener:
```yaml
resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
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
rds:
route_config_name: local_route
config_source:
ads: {}
resource_api_version: V3
http_filters:
- name: envoy.filters.http.filter_chain
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
```

Routes:
```yaml
resources:
- "@type": type.googleapis.com/envoy.config.route.v3.RouteConfiguration
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/mutate"
route:
cluster: service_backend
typed_per_filter_config:
envoy.filters.http.filter_chain:
"@type": type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute
filter_chain:
filters:
- name: envoy.filters.http.header_mutation
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.header_mutation.v3.HeaderMutation
mutations:
request_mutations:
- append:
header:
key: x-route-scope
value: mutate-route
append_action: OVERWRITE_IF_EXISTS_OR_ADD

- match:
prefix: "/"
route:
cluster: service_backend
```

## Risks / compatibility
This could affect users that depend on the current xDS shape.

* EnvoyPatchPolicy: patches targeting listener/HCM filters may break if generated behavior moves into route-level filter_chain config.
* Extension servers: integrations may assume filters are generated at listener/HCM scope and may need updated context or compatibility handling.

## Gaps
Not every Envoy HTTP filter is safe to instantiate from route-level filter_chain config today.

The per-route path uses `createFilterFactoryFromProtoWithServerContext`, while many filters were designed for the listener/HCM FactoryContext path. Filters that depend on listener-specific context, stats scope, config providers, or route-cache behavior may need explicit support before EG can place them in a per-route sub-chain. This still needs envoy upstream work.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.