CORS support for APIs in gateway #541
Replies: 2 comments
-
Key Design Requirements1. CORS as a Regular PolicyCORS must be treated as a regular policy without special handling in the Gateway Controller. The Policy Engine is responsible for all CORS functionality. Design Principle: CORS is not a special case - it is just another policy like any other (apiKey, jwt, rateLimit, etc.). Implications:
2. Automatic OPTIONS Route GenerationThe Gateway Controller must automatically generate OPTIONS routes for all API paths (whether CORS is enabled or not) to handle CORS preflight requests properly. 3. Path-Level CORS Configuration ConflictsCORS configuration must be consistent across all HTTP methods for a given path. However, users can technically define conflicting CORS configurations for different methods on the same path (similar to any other policy). Constraint: The system allows this configuration, but it is invalid and produces undefined behavior. Example - Invalid Configuration: operations:
- method: GET
path: /foo
policies:
- name: cors
params:
allowHeaders: [Get-Header] # CORS config A
- method: PUT
path: /foo
policies:
- name: cors
params:
allowHeaders: [Put-Header] # CORS config B - CONFLICT!Action Required: The CORS policy documentation must explicitly warn users that different CORS configurations for the same path (across different methods) is invalid and will result in undefined behavior. 4. Explicit OPTIONS Route HandlingWhen a user explicitly defines an OPTIONS method for a path, the CORS policy implementation must assume that CORS is handled by the backend and pass the request through without modification. Example: operations:
- method: GET
path: /bar
policies:
- name: cors # Gateway should generate automatic OPTIONS /bar for preflight
- method: OPTIONS
path: /bar # User explicitly defined - passes to backend, no CORS handlingBehavior: The presence of an explicit OPTIONS route takes precedence over automatic CORS preflight handling. 5. API Object in Policy Engine (Same as Application, Subscription in the future)The Policy Engine requires knowledge of all routes defined for an API to properly handle CORS. The Gateway Controller must pass the complete API YAML specification to the Policy Engine. Rationale: CORS headers in preflight responses must accurately reflect all allowed methods for a path, which requires visibility into all operations. Example ConfigurationComplete API with CORS PoliciesapiVersion: gateway.api-platform.wso2.com/v1alpha1
kind: RestApi
metadata:
name: weather-api-v1.0
spec:
displayName: Weather-API
version: v1.0
context: /weather/$version
upstream:
main:
url: http://sample-backend:5000/api/v2
# API-level CORS policy (If user defines here, it applies to all paths and skips operation-level CORS)
policies:
- name: cors
version: v0.1.0
params:
allowOrigins:
- http://example.com
- http://another-example.com
allowMethods: # Defaults to all methods defined for each path
- GET
- POST
- PUT
- DELETE
allowHeaders:
- Content-Type
- Authorization
exposeHeaders:
- X-Custom-Header
allowCredentials: true
maxAge: 3600
operations:
# INVALID: Operation-level CORS overrides for same path (undefined behavior)
# This creates a conflict - path /foo has different CORS configs
- method: GET
path: /foo
policies:
- name: cors
version: v0.1.0
params:
allowHeaders: [Get-Header] # Override for GET
- method: PUT
path: /foo
policies:
- name: cors
version: v0.1.0
params:
allowHeaders: [Put-Header] # CONFLICT: Different config for same path!
- method: GET
path: /bar
policies:
- name: cors
version: v0.1.0
params:
allowHeaders: [Get-Header]
# Explicit OPTIONS route - CORS handled by backend
- method: OPTIONS
path: /bar
# No CORS policy - request passes through to backend |
Beta Was this translation helpful? Give feedback.
-
|
The CORS policy should be a regular policy (available on policy hub, applied through the policy engine). The Gateway should not add any routes automatically. If users require CORS they should define the required resources + method (OPTIONS) and handle CORS by attaching the policy. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
CORS Support
CORS support should be available in the gateway to facilitate browser based clients to access the APIs deployed in the gateway. To cater this requirement, we have two options on our hands.
Option 1 - CORS Policy through policy engine
This will be a policy that can be applied per API. A sample policy definition would look like follows.
Option 2 - Envoy CORS Filter
We will hand over the CORS handling to envoy's CORS filter (https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/cors_filter#config-http-filters-cors).
This filter will be attached to each route. This supports all the parameters defined in the option 1 as well as some additional parameters. More information can be found in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/cors/v3/cors.proto.html#extensions-filters-http-cors-v3-corspolicy
The actual configs will have to be provided through the configuration yaml files. If this is given as a policy, there's nothing to be implemented inside the policy logic.
Concerns
Both these options require an actual route to function. i.e. the gateway should have an OPTIONS route to serve the preflight requests for each of the actual routes. The policy engine creates the policy chain per route and the envoy filter is also attached per route. If the route does not exist, neither of those options would be engaged.
As a solution, we can explore the following
^(GET|OPTIONS)$)Beta Was this translation helpful? Give feedback.
All reactions