Skip to content

HTTP filter that answers preflight requests and stamps CORS headers on responses.

AttachmentType URL (@type)Per-route overrideBuild feature
HTTP filter chain (http_filters)type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors and type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicydisabled onlyNone

What it does

The CORS filter handles cross-origin browser traffic: it answers OPTIONS preflight requests (those carrying access-control-request-method) directly, without going upstream, and adds access-control-* headers to responses for allowed origins. Two type URLs configure the same filter: Cors enables a permissive default policy, CorsPolicy sets an explicit one.

Minimal configuration

The fragment is an entry in http_filters, before the router:

- name: cors
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
    allow_origin_string_match:
      - exact: https://app.example.com
    allow_methods: "GET, POST, PUT, DELETE"
    allow_headers: "authorization, content-type"
    expose_headers: "x-request-id"
    allow_credentials: true
    max_age: "3600"

Fields

Cors takes no fields and enables a permissive default policy: all origins, methods and headers allowed, all headers exposed, no credentials, max_age 86400. CorsPolicy replaces those defaults entirely with:

FieldTypeRequiredDefaultDescription
allow_origin_string_matchlist of string matchersYes—Origins allowed to make cross-origin requests (exact, prefix, suffix, contains or safe_regex, each with optional ignore_case). Left empty, no origin matches.
allow_methodsstringYes—Comma-separated methods for access-control-allow-methods. An empty value fails to parse at startup.
allow_headersstringNononeComma-separated headers allowed in preflight; * allows all when credentials are off. mcp-session-id is always allowed.
expose_headersstringNononeComma-separated headers for access-control-expose-headers. mcp-session-id is always exposed.
allow_credentialsboolNofalseSend access-control-allow-credentials: true.
max_agestringNounsetPreflight cache lifetime in seconds, as a string.

filter_enabled, shadow_enabled, allow_private_network_access and forward_not_matching_preflights are unsupported and refused at startup.

Where policies attach

In Arion the policy attaches at the filter chain: CorsPolicy appears directly in http_filters and applies to every route served by that connection manager. Envoy's other attachment points — the virtual host cors field and CorsPolicy inside typed_per_filter_config — are not supported and are rejected at startup. Per route you can only switch the filter off with a FilterConfig override that sets disabled: true.

Ordering and interactions

Place CORS early in the chain — before authentication — so preflights, which browsers send without credentials, are answered instead of failing JWT checks. The filter never rejects a request itself: traffic from a disallowed origin passes through without CORS headers and the browser blocks the response. Allowed non-preflight requests gain their access-control-* headers on the response path.

Continue

Start typing to search the site.

↑ ↓ to move Enter to open Esc to close