Service Mesh (ASM) implements Layer 7 proxies -- including gateway, sidecar, and waypoint proxies -- on top of Envoy. When built-in capabilities do not meet your requirements, ASM provides five extension methods that let you add custom logic to the Envoy filter chain without rebuilding the proxy binary. Each method makes a different trade-off between performance, flexibility, and development effort.
Choose an extension method
The following table compares the five extension methods.
| Criterion | EnvoyFilter | Lua | Wasm | External Processing | Custom authorization service |
|---|---|---|---|---|---|
| Custom logic | No. Uses built-in Envoy filters only. | Yes. Inline scripts in filter config. | Yes. Standalone binary loaded into the Envoy sandbox. | Yes. Runs as a separate gRPC service. | Limited. Approve or deny requests and modify headers. |
| Protocol support | HTTP and TCP (depends on the filter) | HTTP only | HTTP and TCP | HTTP only | HTTP only |
| Body manipulation | Depends on the filter | Full body buffered in memory -- high memory risk on large payloads | Streaming or buffered -- you choose per request | Full body access through gRPC stream | Read-only |
| Third-party libraries | N/A | Not supported | Supported | Supported (any language) | Supported (any language) |
| Performance overhead | Minimal (compiled C++) | Low (embedded interpreter) | Near-native (sandbox) | Higher (remote gRPC calls) | Higher (remote HTTP or gRPC calls) |
| Development complexity | Medium (requires Envoy internals knowledge) | Low (small scripts) | Medium to high (Rust or C++ recommended) | Medium (implement gRPC interface) | Medium (implement HTTP or gRPC API) |
| Response handling | Yes | Yes | Yes | Yes | No (request-only) |
Quick decision guide:
A built-in filter meets your needs -- Use an EnvoyFilter resource. Simplest path, lowest risk.
Small, HTTP-only customization -- Use Lua. Lightweight and fast to deploy.
Complex logic, performance-sensitive -- Use Wasm. Near-native speed with full protocol support.
Complex logic, latency-tolerant -- Use External Processing. Full language freedom, fully decoupled from Envoy.
Authorization decisions only -- Use a custom authorization service. Stable API, minimal coupling.
Before building a custom extension, check the ASM plug-in center for a built-in plug-in that already covers your use case. The plug-in center includes plug-ins implemented with Envoy native filters, Lua, and Wasm.
How the Envoy filter chain works
Envoy processes each request through an ordered chain of filters. Each filter inspects or modifies the request before passing it to the next filter, and eventually the request reaches the upstream service. All built-in filters are written in C++ and compiled into the Envoy binary.
Lua, Wasm, External Processing, and custom authorization are themselves special-purpose filters that let you run custom logic at defined points in the chain. Among these, External Processing, Lua, and Wasm all support calling external services through the HTTP protocol.
EnvoyFilter
EnvoyFilter is a Kubernetes resource provided by ASM that lets you modify existing filters or add new ones to the data plane proxy by writing raw Envoy configuration.
When to use EnvoyFilter
Use EnvoyFilter when a built-in Envoy filter already provides the behavior you need. Typical examples include customizing error pages and setting cache sizes for 413 Payload Too Large responses.
Limitations
Built-in filters only. Only filters officially shipped with Envoy are available. You cannot inject custom logic.
Requires Envoy internals knowledge. EnvoyFilter requires direct knowledge of Envoy's internal configuration format. Misconfiguration can cause proxy failures or version-incompatibility issues across upgrades.
To reduce version-compatibility risks, use an EnvoyFilter template. For details, see Create an Envoy filter by using an Envoy filter template.
Lua
Envoy includes a built-in Lua filter that runs inline Lua scripts during HTTP request processing. Because the scripts are embedded directly in the filter configuration, there is no separate build or deployment step.
For an example, see Client IP-based routing on ASM ingress gateways.
When to use Lua
Lua works best for short, self-contained customizations that operate on HTTP headers or make simple outbound HTTP calls. The embedded interpreter keeps latency low and deployment simple.
Limitations
HTTP only. Lua scripts cannot manipulate TCP byte streams.
No external libraries. All logic must be self-contained within the inline script. This limits maintainability for complex code.
Body buffering risk. We recommend that you do not handle request or response bodies in Lua code. When a Lua script accesses the request or response body, Envoy buffers the entire payload in memory. Large payloads can cause high memory consumption and
413errors.
Wasm
WebAssembly (Wasm) lets you compile extension code into a portable binary that Envoy loads and runs in a sandbox at near-native speed. Wasm strictly controls the use of resources and interacts with the host through well-defined APIs, enhancing security. Unlike Lua, Wasm extensions are managed as separate artifacts, support third-party libraries, and can be written in multiple languages.
Language-specific development guides:
Advantages over Lua
TCP support. Wasm can manipulate TCP byte streams in addition to HTTP traffic.
Streaming body processing. Process request and response bodies in chunks instead of buffering the entire payload, which reduces memory usage.
Third-party library support. Import external packages for tasks like JSON parsing, cryptography, or protocol handling.
Language considerations
Wasm runtimes have limited support for garbage-collected (GC) languages such as Java, C#, Go, and Python. The community recommends using non-GC languages such as Rust and C++ for better performance.
| Language | Trade-off |
|---|---|
| Go | Easiest to get started with, but Go-compiled Wasm plug-ins consume significantly more memory than their Rust or C++ equivalents. Best for prototyping and latency-tolerant workloads. |
| Rust, C++ | Lower memory usage and higher execution efficiency, but steeper learning curve. Best for production workloads with strict resource budgets. |
External Processing
External Processing is a native Envoy HTTP filter (introduced in Envoy 1.23, supported in ASM 1.15 and later) that calls out to an external gRPC service at configurable stages of HTTP request processing.
The external service can:
Read and modify request and response headers.
Read and modify request and response bodies.
Read and modify Dynamic Stream Metadata, which can feed custom fields into metrics and access logs.
Return a custom response directly, bypassing the upstream.
For an example, see Use Envoy External Processing for custom request handling.
Version history
| ASM version | Capability added |
|---|---|
| 1.15 | External Processing support |
| 1.22 | Envoy metadata and Attributes pass-through |
| 1.24 | Asynchronous invocation mode |
Wasm vs. External Processing
Both methods support complex custom logic for HTTP traffic, but they differ in architecture:
| Criterion | Wasm | External Processing |
|---|---|---|
| Latency | Lower -- runs in-process, no network call | Higher -- requires a remote gRPC call per processing stage |
| Runtime environment | Envoy sandbox. No Linux system calls. | Fully decoupled from Envoy. Any language, any system call. |
When to use External Processing
External Processing is a good fit when your logic is complex, you prefer full language freedom, and the added latency per processing stage is acceptable. Implement the gRPC interface required by Envoy in any language of your choice.
Limitations
HTTP only. External Processing cannot handle TCP byte streams.
Latency compounds. If you process multiple request or response stages, Envoy makes a separate gRPC call for each stage, which increases overall latency.
Custom authorization service
Envoy's external authorization filter calls an HTTP or gRPC service to make allow/deny decisions on incoming requests. The authorization service can also modify or add request headers before the request continues through the filter chain.
Development and configuration guides:
Advantages
Decoupled from Envoy. The authorization service runs independently with a stable API. No dependency on a specific language or framework.
Simple integration. Implement the standard HTTP or gRPC API defined by Envoy.
Limitations
Request-only. The filter applies to requests, not responses.
Read-only body access. The service can read the request body but cannot modify it.
Explicit header allowlisting. The service cannot independently choose which request headers to manipulate. You must configure an explicit allowlist in the EnvoyFilter definition.
Additional latency. The authorization service runs as a separate deployment, adding a network hop to each request.
When to use a custom authorization service
Use a custom authorization service when you need external authorization logic that is more complex than what Lua can handle, Wasm development is too costly, and the limitations above are acceptable for your use case.