---
title: "Wasm"
url: "/reference/filters/http/wasm/"
kind: "reference"
summary: "HTTP filter that runs a WebAssembly module in-process on every request and response."
---

> Arion site index: [/llms.txt](/llms.txt)

# Wasm

HTTP filter that runs a WebAssembly module in-process on every request and response.

| Attachment | Type URL (`@type`) | Per-route override | Build feature |
|---|---|---|---|
| HTTP filter chain (`http_filters`) | `type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm` | `disabled` only | `wasm` |

{{ <badge label="requires: wasm" kind="requires" /> }}

## What it does

The Wasm filter loads a WebAssembly module and runs it in-process against every request and response — header and body access, callouts and shared state, written against the [Arion Rust SDK](@/docs/extend/rust-sdk.md). Arion executes modules on Wasmtime with an asynchronous host, so a plugin that sleeps or waits on a callout yields instead of blocking a worker.

A binary built without the feature rejects any configuration containing this filter at startup:

```bash
cargo build -p arion-proxy --features wasm
```

## Minimal configuration

The fragment is an entry in `http_filters`, before the router:

```yaml,arion=fragment
- name: my_wasm_filter
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
    config:
      name: my_plugin
      root_id: my_plugin
      configuration:
        "@type": type.googleapis.com/google.protobuf.StringValue
        value: '{"greeting": "hello"}'
      vm_config:
        runtime: envoy.wasm.runtime.v8
        code:
          local:
            filename: /etc/arion/plugins/my_plugin.wasm
```

## Fields

All fields live under `config` (Envoy's `PluginConfig`):

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `name` | string | No | — | Plugin name, used in logs. |
| `root_id` | string | No | — | Root context id passed to the module, letting one module serve several configurations. |
| `configuration` | `google.protobuf.StringValue` | No | — | Opaque plugin configuration handed to the module at startup; JSON by convention. |
| `vm_config.runtime` | string | No | — | Accepted for Envoy compatibility (samples use `envoy.wasm.runtime.v8`); Arion always executes on Wasmtime. |
| `vm_config.vm_id` | string | No | — | VM identifier for shared-state scoping. |
| `vm_config.code.local` | data source | Yes | — | The module: `filename`, `inline_bytes`, `inline_string` or `environment_variable`. Remote code sources are rejected. |
| `vm_config.allow_precompiled` | bool | No | `false` | Permit precompiled modules. |

`fail_open`, `failure_policy`, `reload_config`, `capability_restriction_config`, `allow_on_headers_stop_iteration` and `vm_config.environment_variables` are unsupported and refused at startup.

## Ordering and interactions

The module runs at its position in the chain on the request path and in reverse on the response path, and can short-circuit with its own response. Per route it supports only the generic `FilterConfig` override with `disabled: true`. Start with [your first Wasm filter](@/guides/extend/first-wasm-filter.md) for the end-to-end workflow.
