You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #137. That issue bundled two independent surfaces — a low-level HTTPRouteFilter pass-through and a curated CORS block — that close on different
timelines. The filters pass-through stays in #137; this issue tracks the curated
CORS block on its own.
Problem
NebariAppSpec.Routing has no ergonomic way to configure gateway-level CORS for a
NebariApp. The operator already emits a SecurityPolicy per app, and Envoy Gateway's SecurityPolicy.spec.cors is the natural place to express it, but the operator
exposes nothing for it today. Deployers who want CORS handling at the gateway must
fall back to raw routing.filters (the #137 escape hatch) or do it in the backend.
Proposed change
Add a curated CORS *CORSConfig field to RoutingConfig, mirroring Envoy Gateway's
CORS schema, emitted as spec.cors on the SecurityPolicy the operator already
manages:
typeCORSConfigstruct {
// AllowOrigins lists origins permitted to make cross-origin requests. Use a// specific origin when AllowCredentials is true — webhook validation rejects// ["*"] + credentials per CORS spec.AllowOrigins []string`json:"allowOrigins,omitempty"`// AllowMethods lists HTTP methods permitted on cross-origin requests.AllowMethods []string`json:"allowMethods,omitempty"`// AllowHeaders lists request headers the client may use.AllowHeaders []string`json:"allowHeaders,omitempty"`// ExposeHeaders lists response headers the browser exposes to JS.ExposeHeaders []string`json:"exposeHeaders,omitempty"`// MaxAge controls preflight cache duration.MaxAge*metav1.Duration`json:"maxAge,omitempty"`// AllowCredentials enables credentialed CORS requests. When true,// AllowOrigins must not contain "*" (CORS-spec requirement, enforced by// webhook validation).AllowCredentials*bool`json:"allowCredentials,omitempty"`
}
How this relates to the filters pass-through (#137)
routing.cors configures gateway-emitted CORS headers (preflight responses, Access-Control-Allow-Origin injection). Useful when the backend does no CORS.
Filters run after CORS injection in Envoy's chain, so a filter can override
anything the curated block sets.
Scope / priority note
Deferred relative to the filters pass-through. A curated CORS schema is a permanent
contract for the operator to own, so it warrants its own design pass rather than
riding along with the escape hatch. The concrete backend bug that originally
motivated #137 (an upstream emitting an invalid Allow-Credentials: true + Allow-Origin: * combo) has since been fixed at the source in https://redirect.github.com/nebari-dev/nebi/pull/385, so neither half is urgent.
Definition of Done
RoutingConfig.CORS *CORSConfig field added with the fields above
Emitted as spec.cors on the SecurityPolicy the operator already manages
Unit test renders the SecurityPolicy and asserts CORS fields propagate
Behaves correctly when enforceAtGateway: false (SecurityPolicy is dropped) —
either CORS becomes a no-op with a status condition, or the operator keeps a
CORS-only SecurityPolicy
CRD reference documents the field with a CORS example and calls out the
gateway-injected vs. backend-emitted distinction
Summary
Split out of #137. That issue bundled two independent surfaces — a low-level
HTTPRouteFilterpass-through and a curated CORS block — that close on differenttimelines. The filters pass-through stays in #137; this issue tracks the curated
CORS block on its own.
Problem
NebariAppSpec.Routinghas no ergonomic way to configure gateway-level CORS for aNebariApp. The operator already emits a
SecurityPolicyper app, and Envoy Gateway'sSecurityPolicy.spec.corsis the natural place to express it, but the operatorexposes nothing for it today. Deployers who want CORS handling at the gateway must
fall back to raw
routing.filters(the #137 escape hatch) or do it in the backend.Proposed change
Add a curated
CORS *CORSConfigfield toRoutingConfig, mirroring Envoy Gateway'sCORS schema, emitted as
spec.corson the SecurityPolicy the operator alreadymanages:
Sample usage:
How this relates to the filters pass-through (#137)
routing.corsconfigures gateway-emitted CORS headers (preflight responses,Access-Control-Allow-Origininjection). Useful when the backend does no CORS.routing.filters(Routing: expose HTTPRouteFilter pass-through on generated HTTPRoutes #137) modifies any header on the response/request,including those the backend emits. Useful when the backend already does CORS but
does it wrong.
anything the curated block sets.
Scope / priority note
Deferred relative to the filters pass-through. A curated CORS schema is a permanent
contract for the operator to own, so it warrants its own design pass rather than
riding along with the escape hatch. The concrete backend bug that originally
motivated #137 (an upstream emitting an invalid
Allow-Credentials: true+Allow-Origin: *combo) has since been fixed at the source inhttps://redirect.github.com/nebari-dev/nebi/pull/385, so neither half is urgent.
Definition of Done
RoutingConfig.CORS *CORSConfigfield added with the fields abovespec.corson the SecurityPolicy the operator already managesallowOrigins: ["*"]+allowCredentials: trueenforceAtGateway: false(SecurityPolicy is dropped) —either CORS becomes a no-op with a status condition, or the operator keeps a
CORS-only SecurityPolicy
gateway-injected vs. backend-emitted distinction
Related
WebOriginson Keycloak clients; same theme on the IdP sidecurated
cors:block would emit its config