Open-Source Wikis

/

Envoy

/

Background

/

Extension policy

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-static binary.

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:

  1. GitHub issue. Describe the proposed extension and its motivation; link to use cases and existing implementations.
  2. 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).
  3. Two reviewers. Reviewers commit to long-term PR review. They go in CODEOWNERS and can be rotated as needed.
  4. 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.
  5. Dependency policy. New deps must comply with DEPENDENCY_POLICY.md: pinned, security-tracked, build reproducibly.
  6. 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:

  1. GitHub issue lists reasons and replacements.
  2. Factory emits a deprecation warning.
  3. Six-month deprecation window, extendable by another six if it's heavily used.
  4. 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

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Extension policy – Envoy wiki | Factory