Envoy Filter

EnvoyFilter provides a mechanism to customize the Envoy configuration generated by Istio Pilot. Use EnvoyFilter to modify values for certain fields, add specific filters, or even add entirely new listeners, clusters, etc. This feature must be used with care, as incorrect configurations could potentially destabilize the entire mesh. Unlike other Istio networking objects, EnvoyFilters are additively applied. Any number of EnvoyFilters can exist for a given workload in a specific namespace. The order of application of these EnvoyFilters is as follows: all EnvoyFilters in the config root namespace, followed by all matching EnvoyFilters in the workload’s namespace.

NOTE 1: Since this is break glass configuration, there will not be any backward compatibility across different Istio releases. In other words, this configuration is subject to change based on internal implementation of Istio networking subsystem.

NOTE 2: The envoy configuration provided through this mechanism should be carefully monitored across Istio proxy version upgrades, to ensure that deprecated fields are removed and replaced appropriately.

NOTE 3: When multiple EnvoyFilters are bound to the same workload in a given namespace, all patches will be processed sequentially in order of creation time. The behavior is undefined if multiple EnvoyFilter configurations conflict with each other.

NOTE 4: *_To apply an EnvoyFilter resource to all workloads (sidecars and gateways) in the system, define the resource in the config root namespace, without a workloadSelector.

The example below declares a global default EnvoyFilter resource in the root namespace called istio-config, that adds a custom protocol filter on all sidecars in the system, for outbound port 9307. The filter should be added before the terminating tcp_proxy filter to take effect. In addition, it sets a 30s idle timeout for all HTTP connections in both gateays and sidecars.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-protocol
  namespace: istio-config # as defined in meshConfig resource.
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: SIDECAR_OUTBOUND # will match outbound listeners in all sidecars
      listener:
        portNumber: 9307
        filterChain:
          filter:
            name: "envoy.tcp_proxy"
    patch:
      operation: INSERT_BEFORE
      value: |
        name: "envoy.config.filter.network.custom_protocol"
        config:
         ...
  - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
    match:
      # context omitted so that this applies to both sidecars and gateways
      listener:
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
    patch:
      operation: MERGE
      value: |
        idle_timeout: 30s

The following example enables Envoy’s Lua filter for all inbound HTTP calls arriving at service port 8080 of the reviews service pod with labels “app: reviews”, in the bookinfo namespace. The lua filter calls out to an external service internal.org.net:8888 that requires a special cluster definition in envoy. The cluster is also added to the sidecar as part of this configuration.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: reviews-lua
  namespace: bookinfo
spec:
  workloadSelector:
    app: reviews
  configPatches:
    # The first patch adds the lua filter to the listener/http connection manager
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        portNumber: 8080
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
            subFilter:
              name: "envoy.router"
    patch:
      operation: INSERT_BEFORE
      value: # lua filter specification
       name: envoy.lua
       config:
         inlineCode: |
           function envoy_on_request(request_handle)
             -- Make an HTTP call to an upstream host with the following headers, body, and timeout.
             local headers, body = request_handle:httpCall(
              "lua_cluster",
              {
               [":method"] = "POST",
               [":path"] = "/acl",
               [":authority"] = "internal.org.net"
              },
             "authorize call",
             5000)
           end
  # The second patch adds the cluster that is referenced by the lua code
  # cds match is omitted as a new cluster is being added
  - applyTo: CLUSTER
    match:
      context: SIDECAR_OUTBOUND
    patch:
      operation: ADD
      value: # cluster specification
        name: "lua_cluster"
        type: STRICT_DNS
        connect_timeout: 0.5s
        lb_policy: ROUND_ROBIN
        hosts:
        - socket_address:
            protocol: TCP
            address: "internal.org.net"
            port_value: 8888

The following example overwrites certain fields (HTTP idle timeout and X-Forward-For trusted hops) in the HTTP connection manager in a listener on the ingress gateway in istio-system namespace for the SNI host app.example.com:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: hcm-tweaks
  namespace: istio-system
spec:
  workloadSelector:
    istio: ingress-gateway
  configPatches:
  - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
    match:
      context: GATEWAY
      listener:
        filterChain:
          sni: app.example.com
          filter:
            name: "envoy.http_connection_manager"
    patch:
      operation: MERGE
      value: |
        idle_timeout: 30s
        xff_num_trusted_hops: 5

EnvoyFilter

FieldTypeDescription
workloadSelectorWorkloadSelector

Criteria used to select the specific set of pods/VMs on which this patch configuration should be applied. If omitted, the set of patches in this configuration will be applied to all workload instances in the same namespace. If omitted, the EnvoyFilter patches will be applied to all workloads in the same namespace. If the EnvoyFilter is present in the config root namespace, it will be applied to all applicable workloads in any namespace.

configPatchesEnvoyFilter.EnvoyConfigObjectPatch[]

REQUIRED. One or more patches with match conditions.

EnvoyFilter.ApplyTo

ApplyTo specifies where in the Envoy configuration, the given patch should be applied.

NameDescription
INVALID
LISTENER

Applies the patch to the listener.

NETWORK_FILTER

Applies the patch to the network filter chain, to modify an existing filter or add a new filter.

HTTP_FILTER

Applies the patch to the HTTP filter chain in the http connection manager, to modify an existing filter or add a new filter.

CLUSTER

Applies the patch to a cluster in a CDS output. Also used to add new clusters.

EnvoyFilter.ClusterMatch

Conditions specified in ClusterMatch must be met for the patch to be applied to a cluster.

FieldTypeDescription
portNumberuint32

The service port for which this cluster was generated. If omitted, applies to clusters for any port.

servicestring

The fully qualified service name for this cluster. If omitted, applies to clusters for any service. For services defined through service entries, the service name is same as the hosts defined in the service entry.

subsetstring

The subset associated with the service. If omitted, applies to clusters for any subset of a service.

namestring

The exact name of the cluster to match. To match a specific cluster by name, such as the internally generated “Passthrough” cluster, leave all fields in clusterMatch empty, except the name.

EnvoyFilter.DeprecatedListenerMatch.ListenerProtocol

NameDescription
ALL

All protocols

HTTP

HTTP or HTTPS (with termination) / HTTP2/gRPC

TCP

Any non-HTTP listener

EnvoyFilter.DeprecatedListenerMatch.ListenerType

NameDescription
ANY

All listeners

SIDECAR_INBOUND

Inbound listener in sidecar

SIDECAR_OUTBOUND

Outbound listener in sidecar

GATEWAY

Gateway listener

EnvoyFilter.EnvoyConfigObjectMatch

FieldTypeDescription
listenerEnvoyFilter.ListenerMatch (oneof)
routeConfigurationEnvoyFilter.RouteConfigurationMatch (oneof)
clusterEnvoyFilter.ClusterMatch (oneof)

EnvoyFilter.EnvoyConfigObjectPatch

Changes to be made to various envoy config objects.

FieldTypeDescription
applyToEnvoyFilter.ApplyTo

Specifies where in the Envoy configuration, the patch should be applied. The match is expected to select the appropriate object based on applyTo. For example, an applyTo with HTTPFILTER is expected to have a match condition on the listeners, with a network filter selection on envoy.httpconnection_manager and a sub filter selection on the HTTP filter relative to which the insertion should be performed.

matchEnvoyFilter.EnvoyConfigObjectMatch

Match on listener/route configuration/cluster.

patchEnvoyFilter.Patch

The patch to apply along with the operation.

EnvoyFilter.EnvoyFilterMatchCondition

Match conditions for selecting an object to patch.

FieldTypeDescription
contextEnvoyFilter.PatchContext
matchEnvoyFilter.EnvoyConfigObjectMatch

EnvoyFilter.Filter.FilterType

NameDescription
INVALID

placeholder

HTTP

Http filter

NETWORK

Network filter

EnvoyFilter.InsertPosition.Index

Index/position in the filter chain.

NameDescription
FIRST

Insert first

LAST

Insert last

BEFORE

Insert before the named filter.

AFTER

Insert after the named filter.

EnvoyFilter.ListenerMatch

Conditions specified in a listener match must be met for the patch to be applied to a specific listener across all filter chains, or a specific filter chain inside the listener.

FieldTypeDescription
portNumberuint32

The service port/gateway port to which traffic is being sent/received. If not specified, matches all listeners. Even though inbound listeners are generated for the instance/pod ports, only service ports should be used to match listeners.

portNamestring

Instead of using specific port numbers, a set of ports matching a given service’s port name can be selected. Matching is case insensitive.

filterChainEnvoyFilter.ListenerMatch.FilterChainMatch

Match a specific filter chain in a listener. If specified, the patch will be applied to the filter chain (and a specific filter if specified) and not to other filter chains in the listener.

namestring

Match a specific listener by its name. The listeners generated by Pilot are typically named as IP:Port.

EnvoyFilter.ListenerMatch.FilterChainMatch

For listeners with multiple filter chains (e.g., inbound listeners on sidecars with permissive mTLS, gateway listeners with multiple SNI matches), the filter chain match can be used to select a specific filter chain to patch.

FieldTypeDescription
snistring

The SNI value used by a filter chain’s match condition. This condition will evaluate to false if the filter chain has no sni match.

transportProtocolstring

Applies only to SIDECAR_INBOUND context. If non-empty, a transport protocol to consider when determining a filter chain match. This value will be compared against the transport protocol of a new connection, when it’s detected by one of the listener filters.

Accepted values include:

  • raw_buffer - default, used when no transport protocol is detected.
  • tls - set when TLS protocol is detected by the TLS inspector.
filterEnvoyFilter.ListenerMatch.FilterMatch

The name of a specific filter to apply the patch to. Set this to envoy.httpconnectionmanager to add a filter or apply a patch to the HTTP connection manager.

EnvoyFilter.ListenerMatch.FilterMatch

Conditions to match a specific filter within a filter chain.

FieldTypeDescription
namestring

The filter name to match on.

subFilterEnvoyFilter.ListenerMatch.SubFilterMatch

The next level filter within this filter to match upon. Typically used for HTTP Connection Manager filters and Thrift filters. This field is REQUIRED when the apply to is HTTP_FILTER.

EnvoyFilter.ListenerMatch.SubFilterMatch

Conditions to match a specific filter within another filter. This field is typically useful to match a HTTP filter inside the envoy.httpconnectionmanager network filter. This could also be applicable for thrift filters.

FieldTypeDescription
namestring

The filter name to match on.

EnvoyFilter.Patch

Patch specifies the JSON path in the generated proto and the content to merge/remove on the specific path.

FieldTypeDescription
operationEnvoyFilter.Patch.Operation

Determines how the patch should be applied.

valuegoogle.protobuf.Value

The proto equivalent of JSON Value. This will be merged using json merge semantics with the existing proto in the path.

EnvoyFilter.Patch.Operation

Operation denotes how the patch should be applied to the selected configuration.

NameDescription
INVALID
MERGE

Overlay the value onto the element selected by the path using json merge semantics. For primitive fields this is equivalent to ADD.

ADD

For maps this will either add to the map or replace the value for the key. For fields this will replace the value.

REMOVE

Remove the selected elements from their parent. Does not require a value to be specified. When removing fields their values are reset to their intrinsic default.

INSERT_BEFORE

Insert operation on an array of named objects. This operation is typically useful only in the context of filters, where the order of filters matter. For clusters and virtual hosts, order of the element in the array does not matter. Insert before the selected filter or sub filter. If no filter is selected, the specified filter will be inserted at the front of the list.

INSERT_AFTER

Insert operation on an array of named objects. This operation is typically useful only in the context of filters, where the order of filters matter. For clusters and virtual hosts, order of the element in the array does not matter. Insert after the selected filter or sub filter. If no filter is selected, the specified filter will be inserted at the end of the list.

EnvoyFilter.PatchContext

PatchContext selects a class of configurations based on the traffic flow direction and workload type.

NameDescription
ANY

All listeners/routes/clusters in both sidecars and gateways.

SIDECAR_INBOUND

Inbound listener/route/cluster in sidecar.

SIDECAR_OUTBOUND

Outbound listener/route/cluster in sidecar.

GATEWAY

Gateway listener/route/cluster.

EnvoyFilter.RouteConfigurationMatch

Conditions specified in RouteConfigurationMatch must be met for the patch to be applied to a route configuration object or a specific virtual host within the route configuration.

FieldTypeDescription
portNumberuint32

The service port number or gateway server port number for which this route configuration was generated. If omitted, applies to route configurations for all ports.

portNamestring

Applicable only for GATEWAY context. The gateway server port name for which this route configuration was generated.

gatewaystring

The Istio gateway config’s namespace/name for which this route configuration was generated. Applies only if the context is GATEWAY. Should be in the namespace/name format. Use this field in conjunction with the portNumber and portName to accurately select the Envoy route configuration for a specific HTTPS server within a gateway config object.

vhostEnvoyFilter.RouteConfigurationMatch.VirtualHostMatch

Match a specific virtual host in a route configuration and apply the patch to the virtual host.

namestring

Route configuration name to match on. Can be used to match a specific route configuration by name, such as the internally generated “http_proxy” route configuration for all sidecars.

EnvoyFilter.RouteConfigurationMatch.VirtualHostMatch

Match a specific virtual host inside a route configuration.

FieldTypeDescription
namestring

The VirtualHosts objects generated by Istio are named as host:port, where the host typically corresponds to the VirtualService’s host field or the hostname of a service in the registry.

google.protobuf.Value

Value represents a dynamically typed value which can be either null, a number, a string, a boolean, a recursive struct value, or a list of values. A producer of value is expected to set one of that variants, absence of any variant indicates an error.

The JSON representation for Value is JSON value.

FieldTypeDescription
nullValuegoogle.protobuf.NullValue (oneof)

Represents a null value.

numberValuedouble (oneof)

Represents a double value.

stringValuestring (oneof)

Represents a string value.

boolValuebool (oneof)

Represents a boolean value.

structValuegoogle.protobuf.Struct (oneof)

Represents a structured value.

listValuegoogle.protobuf.ListValue (oneof)

Represents a repeated Value.