Open-Source Wikis

/

Envoy

/

Features

/

Wasm

envoyproxy/envoy

Wasm

Envoy embeds a WebAssembly runtime so that filters, access loggers, stat sinks, and bootstrap extensions can be written in any language that compiles to Wasm. The host bindings follow the proxy-wasm ABI. The runtimes plug in via source/extensions/wasm_runtime/; the host glue is in source/extensions/common/wasm/.

Why Wasm?

  • No process boundary. Plugins run in Envoy's address space, with the same memory model and event loop, but in a sandbox.
  • Polyglot. Plugins can be written in Rust, C++, Go (TinyGo), or AssemblyScript and compiled once to a .wasm module.
  • Hot-loadable. Modules can be loaded over xDS (ECDS) and hot-swapped without restart.
  • Sandboxed. No network or filesystem access except through host calls, and host calls are validated.

Where Wasm plugs in

Concern Path Wasm hook
HTTP filter source/extensions/filters/http/wasm/ proxy_on_request_headers, proxy_on_request_body, etc.
Network filter source/extensions/filters/network/wasm/ proxy_on_new_connection, proxy_on_downstream_data.
Access logger source/extensions/access_loggers/wasm/ proxy_on_log.
Stat sink source/extensions/stat_sinks/wasm/ proxy_on_stats_update.
Bootstrap source/extensions/bootstrap/wasm/ Long-lived service, bound at startup.

Runtimes

Pluggable Wasm engines under source/extensions/wasm_runtime/:

Engine Path Notes
v8 v8/ The default; uses Chrome's V8 with a Wasm interpreter.
wasmtime wasmtime/ Bytecode-alliance reference runtime.
wamr wamr/ WebAssembly Micro Runtime.
null null/ "Null vm" — runs a C++ plugin compiled into the binary; useful for tests and embedded scenarios where a real Wasm sandbox isn't desired.

Architecture

graph TB
    Config[ECDS / inline config] --> WasmService[Wasm service<br/>bootstrap]
    WasmService --> Vm[Wasm VM<br/>per worker thread]
    Vm --> Plugin[Plugin instance]
    Plugin -->|host calls| HostBinds[Host functions:<br/>get_header / set_header /<br/>http_call / dispatch_request /<br/>...]
    HostBinds --> Subs[Existing subsystems<br/>filter manager / cluster mgr /<br/>stats / runtime]

A plugin runs in a dedicated VM per worker thread (same threading model as the rest of Envoy — no shared mutable state between workers). The host bindings call back into Envoy's filter manager, cluster manager, stats, runtime, and async client.

Host call vocabulary (proxy-wasm)

The plugin invokes host functions through ABI imports. Common ones:

  • proxy_get_header_map_value, proxy_set_header_map_value — read/write headers.
  • proxy_get_buffer_bytes, proxy_set_buffer_bytes — body manipulation.
  • proxy_dispatch_http_call — make an outbound HTTP call via cluster manager (the host returns control while the call is in flight).
  • proxy_get_property, proxy_set_property — get/set stream info, dynamic metadata, filter state, request attributes (xds.cluster_metadata.foo, etc.).
  • proxy_log — log to Envoy's logger.
  • proxy_define_metric, proxy_record_metric — register and update stats.
  • proxy_continue_request, proxy_send_local_response — control filter chain.

The full ABI is at proxy-wasm/spec; the host implementations are in source/extensions/common/wasm/context.cc and friends.

Plugin lifecycle

  1. Configuration arrives (inline or via ECDS).
  2. Plugin VM is created on each worker (or shared, for singleton plugins).
  3. proxy_on_vm_start runs once per VM.
  4. proxy_on_configure runs once per plugin instance with config bytes.
  5. Per-stream callbacks fire as requests flow.
  6. proxy_on_done / proxy_on_delete fire on plugin removal or shutdown.

Loading

http_filters:
  - name: my_wasm
    typed_config:
      '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
      config:
        vm_config:
          runtime: envoy.wasm.runtime.v8
          code:
            local:
              filename: /etc/envoy/my_filter.wasm
        configuration:
          '@type': type.googleapis.com/google.protobuf.StringValue
          value: '{"my_setting":"value"}'

For dynamic loading, the code field can reference a remote URL or be backed by ECDS.

SDKs

Plugin authors don't usually call the proxy-wasm ABI directly. Language-specific SDKs are maintained in separate repos:

When not to use Wasm

  • Cold latency. Wasm adds a small but non-zero per-call cost; for the hottest filters, a native C++ filter or a dynamic module may be preferable.
  • Polling APIs. Some Envoy capabilities (xDS subscription, stats sink with millions of samples) are too high-throughput to mediate through proxy-wasm gracefully.
  • Outbound TCP. Wasm only exposes HTTP and gRPC outbound calls.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Wasm – Envoy wiki | Factory