Extension Types
Built On Envoy supports several extension types, each suited to different use cases and workflows.
The type field in your extension manifest determines how your extension
is packaged and loaded by Envoy.
Rust Dynamic Module Extensions
Rust extensions are compiled HTTP filters that run inside Envoy as native Dynamic Modules. They use the Rust SDK and are compiled to a C-compatible shared library that Envoy loads directly - no intermediate runtime or plugin loader is needed.
Manifest type: rust
name: my-rust-extension
version: 0.1.0
type: rust
How it Works
- Your extension implements the
HttpFilterConfigandHttpFiltertraits from the Rust SDK. - The crate is compiled with
cargo build --releaseto produce a shared library (.soon Linux,.dylibon macOS). - The corresponding init macro wires up the init and filter-creation entry points that Envoy expects from a dynamic module.
- At runtime, Envoy loads the shared library directly with no additional host module.
Filter Types
Rust extensions support four filter types, controlled by the optional filterType field in your manifest.
The default is http.
| Filter Type | Envoy Layer | Init Macro | Description |
|---|---|---|---|
http (default) |
HTTP (L7) | declare_init_functions! |
Inspect and modify HTTP requests and responses |
network |
TCP/TLS (L4) | declare_network_filter_init_functions! |
Process raw byte streams before HTTP decoding; useful for custom protocols or connection-level access policies |
listener |
Listener (pre-routing) | declare_listener_filter_init_functions! |
Run logic before a TCP connection is routed to a filter chain; useful for connection acceptance policies and pre-routing inspection |
udp_listener |
UDP Listener | declare_udp_listener_filter_init_functions! |
Process UDP datagrams at the listener level |
Getting Started with Rust Extensions
See the Writing Rust Extensions guide for a complete walkthrough of the filter API, lifecycle callbacks, and build process.
Go Extensions
Go extensions are compiled HTTP filters that run inside Envoy through the Dynamic Modules system. They offer full access to the Dynamic Modules Go SDK and support advanced operations such as metrics, body modification, metadata, and local replies.
Manifest type: go
name: my-extension
type: go
composerVersion: 0.2.2
The composerVersion field is required and must match the version of the Composer dynamic module (the special
loader module) that will load the plugin.
How it works
- Your extension exports a
WellKnownHttpFilterConfigFactories()function as its entry point. - The extension is compiled with
go build -trimpath -buildmode=pluginto produce a.sofile. - At runtime, the Composer’s plugin loader opens the
.sofile and validates that it was built with the same Go version and matching dependency versions before registering its filters.
You can see a full example in the extensions/composer/example directory.
Getting Started with Go Extensions
See the Writing Go Extensions guide for a complete walkthrough of the filter API, lifecycle callbacks, and build process.
WASM Go Extensions
WASM extensions are HTTP filters written in Go and compiled to
WebAssembly. Rather than loading native code into the Envoy process, they
run inside Envoy’s built-in WASM runtime
as sandboxed modules that communicate with the host through the
proxy-wasm ABI. Extensions use the
proxy-wasm Go SDK, and the compiled module is
executed by Envoy’s V8 runtime (envoy.wasm.runtime.v8), which ships in official Envoy builds.
The WASM sandbox isolates extension code from the Envoy process: a crashing or misbehaving module cannot corrupt Envoy’s memory. This makes WASM a good middle ground between the raw performance of native Go extensions and the process isolation of ExtProc, without the network latency of an out-of-process server.
Manifest type: wasm
name: my-wasm-extension
version: 0.1.0
type: wasm
How it works
-
Your extension registers a VM context with
proxywasm.SetVMContext()and implements theVMContext,PluginContext, andHttpContextinterfaces from the proxy-wasm Go SDK. -
The module is compiled to WebAssembly with the standard Go toolchain, targeting WASI in
c-sharedmode so it exports the proxy-wasm ABI functions the SDK relies on:env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o plugin.wasm . -
At runtime, Envoy loads the compiled module into a V8 VM and drives the plugin through the proxy-wasm lifecycle callbacks (
OnPluginStart,OnHttpResponseHeaders, and so on).
Filter Types
WASM extensions support HTTP (L7) filters only.
When to Use WASM
WASM extensions are a good fit when you need:
- Sandboxed isolation so extension bugs cannot crash the Envoy process.
- To run inside Envoy without the network round-trip of an ExtProc server.
- Portability of a self-contained, runtime-agnostic module.
Limitations: WASM modules run through the proxy-wasm ABI, which exposes a narrower API surface than the Dynamic Modules Go SDK, and the sandbox adds some overhead compared to native Go extensions. For advanced host integrations or maximum performance, consider a Dynamic Module extension instead.
Lua Extensions
Lua extensions use Envoy’s built-in Lua HTTP filter to run scripts directly inside Envoy with no compilation step. This makes them the simplest way to get started with Built On Envoy.
Manifest type: lua
Providing the Lua Script
The lua field in your manifest defines the script source. You can either reference an external file
or inline the script directly.
File reference:
name: my-lua-extension
type: lua
lua:
path: plugin.lua
Inline script:
name: my-lua-extension
type: lua
lua:
inline: |
function envoy_on_request(request_handle)
request_handle:headers():add("x-custom-header", "hello")
end
function envoy_on_response(response_handle)
response_handle:headers():add("x-response-header", "world")
end
You must provide exactly one of path or inline - not both.
When to Use Lua
Lua extensions are a good fit when you need:
- Quick header manipulation or request routing logic
- Simple request/response transformations without a build step
- Rapid prototyping before investing in a compiled extension
Limitations: Lua extensions have access only to the APIs exposed by Envoy’s Lua filter. For advanced features like custom metrics, body buffering, or tight performance requirements, consider a Go extension instead.
ExtProc extensions
ExtProc extensions are Envoy External Processing gRPC servers that run outside the main Envoy process. The gRPC offers methods to manipulate the request and response metadata and payloads, but is much more complex to use than the Dynamic Modules API.
Using ExtProc extensions introduces latency and serialization overhead, but it is a good approach for extensions that are preferred to run outside the main Envoy process to make sure the extension code cannot affect the Envoy main process.
Manifest type: ext_proc
name: my-extproc-extension
type: ext_proc
version: 0.2.2
extProc:
grpcPort: 50051
failureModeAllow: false
processingMode:
requestHeaderMode: SEND
responseHeaderMode: SEND
requestBodyMode: BUFFERED
responseBodyMode: NONE
How it works
- Your extension implements the Envoy
ExternalProcessorServergRPC service interface. - The extension is compiled into a standalone binary that is started in parallel to Envoy.
- Envoy is configured to forward requests and responses to the external processor server.
You can see a full example in the extensions/example-ext-proc directory.