envoyproxy / envoyproxy/gateway
Support a local/filesystem Wasm code source in EnvoyExtensionPolicy
- 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