| title | Configuring CORS |
|---|---|
| subtitle | Control browser access to your router |
| description | Manage browser access to your Apollo GraphOS Router or Apollo Router Core with CORS configuration options, including origin whitelisting, wildcard origins, and credential passing. |
This article describes CORS configuration that's specific to the GraphOS Router and Apollo Router Core. For a more general introduction to CORS and common considerations, see the following sections:
By default, the router enables only GraphOS Studio to initiate browser connections to it. If your supergraph serves data to other browser-based applications, you need to do one of the following in the cors section of your router's YAML config file:
-
Add the origins of those web applications to the router's list of allowed
policies.- Use this option if there is a known, finite list of web applications that consume your supergraph.
-
Add a regex that matches the origins of those web applications to the router's list of allowed
policies.- This option comes in handy if you want to match origins against a pattern, see the example below that matches subdomains of a specific namespace.
-
Enable the
allow_any_originoption.- Use this option if your supergraph is a public API with arbitrarily many web app consumers.
- With this option enabled, the router sends the wildcard (
*) value for theAccess-Control-Allow-Originheader. This enables any website to initiate browser connections to it (but they can't provide cookies or other credentials).
-
If clients need to authenticate their requests with cookies, you must use either
origins,match_origins, or the combination of both options. When using both options, note thatoriginsis evaluated beforematch_origins.
The following snippet includes an example of each option (use either allow_any_origin, or origins and/or match_origins):
cors:
# Set to true to allow any origin
# (Defaults to false)
allow_any_origin: true
# List of accepted origins
# (Ignored if allow_any_origin is true)
# (Defaults to the GraphOS Studio url: `https://studio.apollographql.com`)
#
# An origin is a combination of scheme, hostname and port.
# It does not have any path section, so no trailing slash.
policies:
- origins:
- https://www.your-app.example.com
- https://studio.apollographql.com # Keep this so GraphOS Studio can run queries against your router
match_origins:
- "^https://([a-z0-9]+[.])*api[.]example[.]com$" # any host that uses https and ends with .api.example.comYou can also disable CORS entirely by setting policies to an empty list:
cors:
policies: []If your router serves exclusively non-browser-based clients, you probably don't need to modify the default CORS configuration.
If your router requires requests to include a user's credentials (e.g., via cookies), you need to modify your CORS configuration to tell the browser those credentials are allowed.
You can enable credentials with CORS by setting the Access-Control-Allow-Credentials HTTP header to true.
To allow browsers to pass credentials to the router, set allow_credentials to true, like so:
cors:
policies:
- origins:
- https://www.your-app.example.com
- https://studio.apollographql.com
allow_credentials: trueTo support credentialed requests, your router's config file must specify individual origins. If your router enables allow_any_origin, your browser will refuse to send credentials.
Additionally, you'll need to configure the router to forward the Cookie header to some (or all) of your subgraphs:
headers:
all:
request:
- propagate:
named: cookieFor examples of sending cookies and authorization headers from Apollo Client, see Authentication.
By default, browsers block any requests sent to a device or service on a private network. If your router requires requests to a device or service on a private network, you need to enable this behavior in your CORS configuration.
To enable private network access with CORS, your router must return the Access-Control-Allow-Private-Network HTTP header with a value of true. To do so, add the private_network_access with an empty access_id value in the policies of your cors config.
cors:
policies:
- origins:
- https://www.your-app.example.com
- https://studio.apollographql.com
private_network_access:
access_id:Optionally, you can specify the access_id and access_name subfields to identify what is being accessed in the private network when the browser prompts the user for permission. These fields return the Private-Network-Access-ID and Private-Network-Access-Name HTTP headers, respectively, along with the specified strings.
cors:
policies:
- origins:
- https://www.your-app.example.com
- https://studio.apollographql.com
private_network_access:
access_id: "01:23:45:67:89:0A"
access_name: "mega-corp device"Individual policies within the policies array inherit global CORS settings unless explicitly overridden:
- Allow credentials: Policies inherit the global
allow_credentialssetting unless they specify their own value - Allow headers: Policies inherit global headers if their
allow_headersis empty, otherwise use policy-specific headers - Expose headers: Policies inherit global headers if their
expose_headersis empty, otherwise use policy-specific headers - Methods: Policies have three inheritance states:
- Not specified (
null): Inherits globalmethods - Empty array (
[]): No methods allowed for this policy - Specific values: Uses those exact methods
- Not specified (
- Max age: Policies inherit the global
max_ageunless they specify their own value
The following snippet shows all CORS configuration defaults for the router:
#
# CORS (Cross Origin Resource Sharing)
#
cors:
# Set to true to allow any origin
allow_any_origin: false
# List of accepted origins
# (Ignored if allow_any_origin is set to true)
#
# An origin is a combination of scheme, hostname and port.
# It does not have any path section, so no trailing slash.
policies:
- origins:
- https://studio.apollographql.com # Keep this so GraphOS Studio can still run queries against your router
# Enable private network access for the router
private_network_access:
access_id:
# Set to true to add the `Access-Control-Allow-Credentials` header
allow_credentials: false
# The headers to allow.
# Not setting this mirrors a client's received `access-control-request-headers`
# This is equivalent to allowing any headers,
# except it will also work if allow_credentials is set to true
allow_headers: []
# Allowed request methods
methods:
- GET
- POST
- OPTIONS
# Which response headers are available to scripts running in the
# browser in response to a cross-origin request.
expose_headers: []
# Adds the Access-Control-Max-Age header
# Can be set to a duration in time units
# If not set, the header is not included
max_age: 2hA plugin may set a response Vary header. If, after all plugins are processed, there is no response Vary header, then the router will add one with a value of "origin".