Updated on 2025-01-07 GMT+08:00

Configuring Cross-Origin Access for Nginx Ingresses

The same-origin policy of browsers prevents a web page loaded by one origin from directly requesting resources from another origin in web development. Cross-origin resource sharing (CORS) is a secure solution that allows cross-origin requests.

CORS can be used in the following scenarios:

  • Separated frontend and backend: In web development, frontend applications are often deployed under a domain name (for example, frontend.example.com), while the backend API service uses a different domain name (for example, api.example.com). This can cause cross-origin resource sharing to be blocked, but CORS can help resolve this issue by allowing the frontend to obtain data from the API service.
  • Third-party service integration: If your website needs to call third-party APIs (for example, the APIs of a map service or social media login platform), configure CORS to enable cross-origin resource sharing.
  • CDN: If your website is using a CDN to provide static resources from a domain name that differs from the primary domain, you can use CORS to load these resources.

Configuration Example

This section uses the communication between a frontend application (frontend.example.com) and a backend API service (api.example.com) as an example to describe how to add an annotation to the ingress for cross-origin access. For details about the annotation, see Enable CORS.

Example configuration:

apiVersion: networking.k8s.io/v1 
kind: Ingress 
metadata:
  name: test-ingress 
  namespace: default 
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"     # Enable CORS.
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"  # Configure the origin that can be accessed.
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"  # Allowed HTTP request methods
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"  # Allowed request headers
    nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"  # Response headers to be exposed
    nginx.ingress.kubernetes.io/cors-max-age: "3600"  # Cache duration of a pre-check request
spec:
  rules:
    - host: api.example.com 
      http:
        paths:
          - path: /
            backend:
              service:
                name: example
                port:
                  number: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
  ingressClassName: nginx
Table 1 Parameters for configuring cross-origin access

Parameter

Description

Example

nginx.ingress.kubernetes.io/enable-cors

Enable CORS to allow cross-origin access.

nginx.ingress.kubernetes.io/enable-cors: "true"

nginx.ingress.kubernetes.io/cors-allow-origin

Specify Access-Control-Allow-Origin for the origin that can be accessed.

The parameter value is in the format of http(s)://example.com or http(s)://example.com:port. You can enter multiple values by separating them with commas (,).

Wildcards are also supported. For example:

  • * indicates that access from all domains is allowed.
  • Enter a level-1 wildcard domain name. For example, http(s)://*.example.com indicates that all subdomain names under the domain name can be accessed.
NOTICE:

To enhance security, specify a domain name to prevent unauthorized access to sensitive resources from other domains.

nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"

nginx.ingress.kubernetes.io/cors-allow-methods

Specify Access-Control-Allow-Methods for allowed HTTP request methods.

You can enter multiple values by separating them with commas (,).

nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"

nginx.ingress.kubernetes.io/cors-allow-headers

Specify Access-Control-Allow-Headers for allowed request headers.

You can enter multiple values by separating them with commas (,).

nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range"

nginx.ingress.kubernetes.io/cors-allow-credentials

Specify Access-Control-Allow-Credentials to control the sending of credentials (such as cookies).

Options:

  • true: Credentials can be sent.
  • false: Credentials cannot be sent.
NOTICE:

For security purposes, if Access-Control-Allow-Credentials is set to true, the wildcard (*) cannot be used for Access-Control-Allow-Origin. This prevents unauthorized domains from accessing sensitive resources, such as cookies or authorization headers containing user credentials.

nginx.ingress.kubernetes.io/cors-allow-credentials: "true"

nginx.ingress.kubernetes.io/cors-expose-headers

Specify Access-Control-Expose-Headers for custom response headers that can be accessed by a cross-origin request. This allows you to retrieve non-standard response headers using client-side JavaScript code.

For security purposes, browsers can only access standard response headers including Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, and Pragma, when handling cross-origin requests, unless otherwise specified.

You can enter multiple values by separating them with commas (,).

nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"

nginx.ingress.kubernetes.io/cors-max-age

Specify Access-Control-Max-Age for the cache duration of a CORS pre-check request.

Properly configure this parameter based on service requirements. If the value is too low, pre-check requests may happen frequently. If the value is too high, the CORS policy may not take effect immediately.

nginx.ingress.kubernetes.io/cors-max-age: "3600"

Verifying Cross-Origin Access

Use curl to send a cross-origin request and check the response header.

curl -X OPTIONS -H 'Origin: {Origin}' {Accessed ingress URL} -i

For example, if the origin is frontend.example.com and the accessed ingress URL is api.example.com, run the following command:

curl -X OPTIONS -H 'Origin: frontend.example.com' api.example.com -i

The Access-Control-** request header will be added to the original backend response.

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS 
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range 
Access-Control-Expose-Headers: Content-Length,Content-Range 
Access-Control-Allow-Credentials: true 
Content-Type: application/json