CORS
Specify external domains that can access your routes with cross-origin resource sharing.
For example, you can configure requests that are made on your behalf. At the same time, you can block requests that are made by attacks, such as Javascript code or malware. Consider the following request scenarios that you can configure with CORS.
- A different domain, such as
example.comsite callsapi.com - A different subdomain, such as
example.comcallsapi.example.com - A different port, such as
example.comcallsexample.com:3001 - A different protocol, such as
https://example.comcallshttp://example.com
For more information, see the following resources.
If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.
If you apply a CORS policy to a route, the CORS policy is added inline on the resulting Istio VirtualService. In environments with large RouteTable delegation trees, the size of VirtualServices can grow quickly and exceed the maximum size in Kubernetes, especially if additional policies, such as CORS, are attached to a route. You can change the translation mode for CORS policies and instead add them as separate EnvoyFilters by setting the
GLOO_CORS_TRANSLATION_MODE environment variable on the Gloo management server to VS_and_EF or EF_only. For more information, see GLOO_CORS_TRANSLATION_MODE.Before you begin
This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started. If you have different names, make sure to update the sample configuration files in this guide.
Configure CORS policies
You can apply a CORS policy at the route level. For more information, see Applying policies.
You cannot apply this policy to a route that already has a redirect, rewrite, or direct response action. Keep in mind that these actions might not be explicitly defined in the route configuration. For example, invalid routes are automatically replaced with a direct response action, such as when the backing destination is wrong. First, verify that your route configuration is correct. Then, decide whether to apply the policy. To apply the policy, remove any redirect, rewrite, or direct response actions. To keep the actions and not apply the policy, change the route labels of either the policy or the route.
Review the following sample configuration files.
apiVersion: security.policy.gloo.solo.io/v2
kind: CORSPolicy
metadata:
name: simple-cors
namespace: bookinfo
spec:
applyToRoutes:
- route:
labels:
route: ratings
config:
maxAge: 1m
allowCredentials: true
allowHeaders:
- foo
- bar
allowMethods:
- GET
allowOrigins:
- exact: http://istio.io Review the following table to understand this configuration. For more information, see the API docs.
| Setting | Description |
|---|---|
spec.applyToRoutes | Use labels to configure which routes to apply the policy to. This example label matches the app and route from the example route table that you apply separately. If omitted and you do not have another selector such as applyToDestinations, the policy applies to all routes in the workspace. |
maxAge | Optionally specify how long the results of a preflight request are cached. This value translates to the Access-Control-Max-Age header. In this example, the value is 1m. |
allowCredential | Optionally let the caller send the actual request with credentials, not just the preflight request. This value translates to the Access-Control-Allow-Credentials header. In this example, the value is true. |
allowHeaders | Specify a list of HTTP headers that can be used in requests. This value is serialized to the Access-Control-Allow-Headers header. In this example, the foo and bar headers can be used in the request. |
allowMethods | Specify a list of HTTP methods that can be used in requests. This value is serialized to the Access-Control-Allow-Methods header. In this example, only the GET method can be used to access the resource. |
allowOrigins | Enter a string pattern to use to decide if an origin is allowed. An origin is allowed if any of the string patterns match the origin in the header. You can set up exact, prefix, suffix, or regex matches. By default, matching is case-sensitive for exact, prefix, and suffix matching, unless you include ignoreCase: true. This value is serialized to the Access-Control-Allow-Origin header. In this example, the origin header must match exactly http://istio.io. |
Verify CORS policies
- Apply the example CORS policy in the cluster with the Bookinfo workspace in your example setup.
kubectl apply -f - << EOF apiVersion: security.policy.gloo.solo.io/v2 kind: CORSPolicy metadata: name: simple-cors namespace: bookinfo spec: applyToRoutes: - route: labels: route: ratings config: maxAge: 1m allowCredentials: true allowHeaders: - foo - bar allowMethods: - GET allowOrigins: - exact: http://istio.io EOF Send a request to the app.
- HTTP:
curl -vik -H "Origin: http://istio.io" -H "Access-Control-Request-Method: GET" -X OPTIONS --resolve www.example.com:80:${INGRESS_GW_ADDRESS} https://www.example.com:80/ratings/1 - HTTPS:
curl -vik -H "Origin: http://istio.io" -H "Access-Control-Request-Method: GET" -X OPTIONS --resolve www.example.com:443:${INGRESS_GW_ADDRESS} https://www.example.com:443/ratings1
Example response:
HTTP/1.1 200 OK
access-control-allow-origin: http://istio.io
access-control-allow-credentials: true
access-control-allow-methods: GET
access-control-allow-headers: foo,bar
access-control-max-age: 60 Cleanup
You can optionally remove the resources that you set up as part of this guide.kubectl -n bookinfo delete CORSPolicy simple-cors