---
title: "Extending Arion"
url: "/docs/extend/overview/"
kind: "concept"
summary: "Choose between a WASM filter, an external processing service, or a native Rust filter to run your own logic in the request path."
---

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

# Extending Arion

Choose between a WASM filter, an external processing service, or a native Rust filter to run your own logic in the request path.

Arion gives you three ways to run your own code on every HTTP request: a WebAssembly filter loaded into the proxy, an external processing service called over gRPC, or a native filter compiled into the binary. All three plug into the same HTTP filter chain — the difference is where your code runs and what it costs to get it there.

## Why it matters

Most gateway behaviour is configuration: routing, TLS, rate limits, JWT validation. Extension is for the part that is genuinely yours — a bespoke auth handshake, request rewriting driven by your own data, a protocol adaptation no config flag covers. Picking the right extension point early matters because the three options trade off latency, isolation, and operational effort differently, and switching later means rewriting.

## How it works

Every option is an HTTP filter inside the [filter chain](@/docs/concepts/filter-chain.md). Filters run in configured order on the request path and in reverse order on the response path; each one can pass the message on, mutate it, or answer the client directly.

{{ <figure src="img/docs/extend-choices.svg" alt="The Arion HTTP filter chain with a native filter and a WASM filter inside the process, and an ext_proc filter streaming to an external gRPC service" caption="Three extension points on one filter chain: native code in the binary, a sandboxed WASM module in the process, and an out-of-process gRPC service." label="Figure 1." /> }}

**WASM filter.** You write a plugin in Rust with the [Arion SDK](@/docs/extend/rust-sdk.md), compile it to a `.wasm` module, and reference the file from config. Arion runs it in-process on the embedded Wasmtime engine — sandboxed, with instances pooled and reused across requests. Calls into the module are function calls, not network traffic. See [WASM filters](@/docs/extend/wasm-filters.md).

**External processing (ext_proc).** Arion streams request and response phases over a bidirectional gRPC stream to a service you run anywhere, in any language. Your processor returns mutations or an immediate response. Full control, at the cost of a network hop per processed message. See [External processing](@/docs/extend/ext-proc.md).

**Native filter.** A Rust filter compiled into Arion itself — the mechanism behind the built-in filters. It has zero serialization overhead and full access to internals, but shipping one means contributing to Arion and rebuilding the binary. See [Native HTTP filters](@/docs/extend/http-filters-in-rust.md).

## Comparison

| | WASM filter | ext_proc | Native filter |
|---|---|---|---|
| Runs | In-process, sandboxed | Separate service | In the binary |
| Language | Rust (SDK) | Any with gRPC | Rust |
| Overhead | In-process calls | gRPC hop per message | None added |
| Body access | Full, buffered | Streamed or buffered | Full |
| Deploy | Ship a `.wasm` file + config | Deploy your service | Rebuild Arion |
| Per-route | Disable only | Disable or override | Filter-specific |
| Pick when | Custom logic close to the wire | Existing code, any language, heavy logic | Core features for everyone |

## Policy is configuration, not extension

Do not write a plugin for authentication or authorization that Arion already ships: [JWT validation](@/docs/security/jwt.md), [RBAC](@/docs/security/rbac.md), and [Cedar policies](@/docs/security/cedar-policies.md) are built-in filters you configure. Reach for an extension only when no built-in filter expresses your rule.

MCP [code mode](@/docs/mcp-gateway/code-mode.md) runs agent-written TypeScript inside Arion too, but it is not an extension point. Its scripts can only call the gateway's tools, and they never see or change the requests passing through the proxy.

## Key terms

- **Filter chain** — the ordered list of HTTP filters a request passes through; see [the filter chain](@/docs/concepts/filter-chain.md).
- **Plugin** — a `.wasm` module implementing the SDK's `Plugin` trait, loaded by the `wasm` filter.
- **Processor** — your gRPC service implementing the ext_proc protocol.
- **Filter decision** — what a filter returns: continue, re-route, or answer the client directly.

## Next

Start with [WASM filters](@/docs/extend/wasm-filters.md) for the operator view, the [Rust SDK](@/docs/extend/rust-sdk.md) to write one, or [External processing](@/docs/extend/ext-proc.md) if your logic lives in another language or service.
