envoyproxy/envoy
Extension policy
Extensions are how Envoy stays small at the core and big at the edges. The full policy is in EXTENSION_POLICY.md; this page summarises and frames it.
The bargain
The core idea: anything that lives in source/extensions/ is held to the same quality bar as core code. Same coding style, same review depth, same test coverage, same security stance. In exchange:
- Core refactors will keep the extension working — every contributor automatically owns the burden of fixing extension call sites when core APIs change.
- The extension benefits from CI infrastructure, sanitiser builds, fuzzing, scaling tests.
- The extension is shipped in the canonical
envoy-staticbinary.
If an extension can't meet that bar — because of vendor-only dependencies, restrictive licences, or experimental status — it lives in contrib/ and ships in envoy-contrib instead.
Adding an extension
The procedure has six steps:
- GitHub issue. Describe the proposed extension and its motivation; link to use cases and existing implementations.
- Sponsor. An existing maintainer must agree to shepherd the extension through reviews. Without a sponsor, the proposal stalls. Maintainers can self-sponsor (and often do for extensions they wrote).
- Two reviewers. Reviewers commit to long-term PR review. They go in
CODEOWNERSand can be rotated as needed. - Repo membership. Once merged, the extension is part of the repo. API-breaking core changes will fix the extension as part of the normal PR.
- Dependency policy. New deps must comply with
DEPENDENCY_POLICY.md: pinned, security-tracked, build reproducibly. - Platform guards. Platform-specific code is guarded in the build system; tests are skipped on unsupported platforms.
Removing an extension
If an extension goes unmaintained:
- GitHub issue lists reasons and replacements.
- Factory emits a deprecation warning.
- Six-month deprecation window, extendable by another six if it's heavily used.
- After the window, the extension source is removed.
Status and security posture tags
Every envoy_cc_extension rule carries two metadata fields:
status:
| Value | Meaning |
|---|---|
stable (default) |
Production-ready. |
alpha |
Functional but not production-burned. |
wip |
Incomplete; not for production. |
security_posture:
| Value | Meaning |
|---|---|
robust_to_untrusted_downstream |
Safe to expose to untrusted downstreams; assumes trusted upstreams. |
robust_to_untrusted_downstream_and_upstream |
Safe in both directions. |
requires_trusted_downstream_and_upstream |
Use only inside a trust boundary. |
unknown |
Equivalent to "trusted both"; placeholder. |
data_plane_agnostic |
Not on the data plane (e.g. stat sinks). |
These are surfaced in extensions_metadata.yaml and at the admin endpoint, and they affect the security team's escalation behaviour: a CVE in an extension labelled requires_trusted_downstream_and_upstream is not escalated the same way as one in a robust_to_untrusted_downstream extension.
Wasm rule
Wasm extensions are explicitly not allowed in envoyproxy/envoy, except as part of validating the Wasm implementation. Why?
- Wasm modules sit behind a version-independent ABI; in-tree validation adds little.
- Wasm modules pull in language-specific dependencies (Rust crates, Go modules) that the repo doesn't want to maintain.
- The project doesn't write production extensions in Wasm.
Author Wasm modules in your own repo or a third-party one; the Envoy repo only hosts the proxy-wasm host bindings.
PRs to extensions
Extension PRs must not modify core code. If they need to, the core change goes in a separate PR with normal core review. Extension PRs need approval from one sponsoring maintainer plus one of the extension's reviewers. Both can be the same person if no one else is around — but that's an exception, not the norm.
Naming
Extensions follow the pattern envoy.<area>.<name>:
envoy.filters.http.<name>envoy.filters.network.<name>envoy.filters.listener.<name>envoy.transport_sockets.<name>envoy.access_loggers.<name>envoy.tracers.<name>envoy.stat_sinks.<name>envoy.clusters.<name>envoy.load_balancing_policies.<name>- etc.
Avoid vendor names in the path unless the extension is tied to a specific vendor's protocol or product.
Why all this matters
The policy looks bureaucratic, but it serves the project's most important property: operators can deploy a stock Envoy and reasonably expect every extension to be production-ready, security-tracked, and supported. The contrib path exists to keep that promise true while still providing a place for non-conforming extensions to live.
See also
EXTENSION_POLICY.md— authoritative source.GOVERNANCE.md— how maintainers are made and removed.- envoy-contrib — where lower-bar extensions live.
- HTTP filters, Network filters, etc. — concrete extension families.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.