envoyproxy / envoyproxy/gateway

Support a local/filesystem Wasm code source in EnvoyExtensionPolicy

Open
#9,448 4 comments 2 reactions 0 assignees View on GitHub
kind/feature stale
Dominant language
Go
Stars
3k
Forks
864
Avg merge
2d 2h
Merged PRs (30d)
140

Description

Would the maintainers be open to adding a local file code source for Wasm, alongside the existing `HTTP` and `Image` types? Happy to write the PR if there's appetite, wanted to check the design direction first.

**Why**
I'm running a Wasm filter as a hard security boundary (`failOpen: false`). Today every code source (`Image`, `HTTP`, `ConfigMap`) is fetched by the control plane, cached, and then served to Envoy over HTTP. The translator always emits an `AsyncDataSource.remote` (`internal/xds/translator/wasm.go`). That means there's always a window at config-apply time where the proxy has the xDS config but the module hasn't been fetched yet. For a fail-closed filter that window is a `Plugin configured to fail closed failed to load` critical and transient request rejections on the route until the fetch completes. It's usually brief, but for a security-critical route "usually brief" isn't great, and it makes rollouts noisier than they should be.

Envoy itself already supports a local `AsyncDataSource` (`vm_config.code.local.filename`), Envoy Gateway just doesn't expose it. If the module is already present on the proxy, there's no fetch, no cache dependency, and no null-VM window.

We prefer to steer away from EnvoyPatchPolicies in the long run, hence I'm seeking official support to bake WASM modules into the Envoy Proxy image.

**Proposal**
Add a `Filename` (or `Local`) `WasmCodeSourceType`:

```yaml
wasm:
- name: my-filter
code:
type: Filename
filename:
path: /var/lib/envoy/my-filter.wasm
sha256: ""
```

Translator emits `AsyncDataSource.local` instead of `remote`, and the control-plane fetch/cache path is skipped entirely.

The obvious tradeoff: EG can't place the file on the proxy, so provisioning it (custom proxy image, or a mounted volume/initContainer) becomes the operator's responsibility. So this is an advanced/opt-in option, not a replacement for the managed sources. But for air-gapped setups and fail-closed filters it's the reliable path.

**Alternatives considered**

- `EnvoyPatchPolicy` can already produce the local data source config, but it's Gateway-scoped, so you lose the per-route targeting that `EnvoyExtensionPolicy` gives you for free.
- Pinning `sha256` + pull policy tuning helps with re-fetch churn but doesn't remove the initial apply-time window.

Loosely related: #7886 (remote OCI fetch failures having outsized blast radius) is another case where the remote-fetch dependency bites, a local source sidesteps that class of problem for people who can provision the file.

Would a first-class local source be welcome, or is keeping fetch centralized in the control plane a deliberate line you'd rather not cross? Either way, thanks.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with internal/xds/translator/wasm.go and trace how the existing HTTP, Image, and ConfigMap sources become AsyncDataSource.remote. Check the EnvoyExtensionPolicy API definitions and related tests, then confirm the design direction with maintainers before implementation. Done means a supported local filename source produces AsyncDataSource.local without the control-plane fetch path.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes, wasm
Domain
api, backend, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.