Skip to main content
Version: main 🚧

Configure CORS policy

Configure Cross-Origin Resource Sharing (CORS) headers at the ingress level so external browser-based clients can make API requests to vCluster Platform.

Prerequisites​

  • A deployed vCluster Platform instance with external access configured.
  • An ingress controller (such as ingress-nginx) deployed on the host cluster.
  • helm v3.10+ and kubectl with admin access to the cluster.

Overview​

If you build browser-based tools, such as a custom operations dashboard, a monitoring UI, or a CI interface, that call the Platform API from a different domain, browsers block those requests by default. This is the same-origin policy. CORS headers tell the browser which external origins are allowed.

For example, a dashboard at https://dashboard.example.com that fetches data from the Platform API at https://platform.example.com fails unless the Platform ingress returns the correct CORS headers.

When CORS configuration is needed

The Platform UI and API share the same origin. Normal Platform access, kubectl commands, and in-cluster service-to-service traffic don't require CORS. Configure CORS only when a browser-based application at a different origin calls the Platform API.

The Platform doesn't set CORS headers by default. Add them through your ingress controller.

Configure ingress-level CORS​

ingress-nginx​

  1. Create or update your vcluster-platform.yaml with CORS annotations on the Platform ingress:

    Modify the following with your specific values to generate a copyable command:
    vcluster-platform.yaml
    ingress:
    enabled: true
    host: "platform.example.com"
    annotations:
    # CORS
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://dashboard.example.com"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Authorization, Content-Type"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "3600"
    tls:
    enabled: true
    secret: tls-vcluster-platform
  2. Apply the configuration:

    Modify the following with your specific values to generate a copyable command:
    Upgrade the Platform with CORS annotations
    helm upgrade vcluster-platform vcluster-platform \
    --repo https://charts.loft.sh/ \
    --namespace vcluster-platform \
    --reuse-values \
    -f vcluster-platform.yaml
  3. Verify the ingress returns CORS headers by sending a preflight request:

    Modify the following with your specific values to generate a copyable command:
    Test CORS preflight
    curl -v -X OPTIONS \
    -H "Origin: https://dashboard.example.com" \
    -H "Access-Control-Request-Method: GET" \
    https://platform.example.com/kubernetes/management/apis

    A correct response includes these headers:

    Access-Control-Allow-Origin: https://dashboard.example.com
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
    Access-Control-Allow-Headers: Authorization, Content-Type

    If these headers are missing, check the ingress annotations and confirm the ingress controller processes them.

Annotation reference​

All annotations use the nginx.ingress.kubernetes.io/ prefix.

AnnotationDescriptionDefault
enable-corsEnable CORS headers"false"
cors-allow-originAllowed origins (comma-separated)"*"
cors-allow-methodsAllowed HTTP methods"GET, PUT, POST, DELETE, PATCH, OPTIONS"
cors-allow-headersAllowed request headersStandard browser headers and Authorization
cors-allow-credentialsAllow credentials (cookies, auth)"false"
cors-expose-headersResponse headers exposed to browser(none)
cors-max-agePreflight cache duration in seconds"1728000"
warning

Don't set cors-allow-origin to "*" when cors-allow-credentials is "true". Browsers reject this combination per the CORS specification. List explicit origins instead.

Other ingress controllers​

Traefik, Istio, and Gateway API support CORS through their own configuration:

Security considerations​

Restrict allowed origins​

Setting cors-allow-origin to "*" disables CORS protection. Any website a user visits can make cross-origin requests to the Platform API.

danger

Never use cors-allow-origin: "*" in production. List only the specific domains that need access.

  • Prefer explicit origins (https://dashboard.example.com) over wildcards.
  • Separate development and production configurations. Don't include localhost origins in production values.

CORS doesn't replace authentication​

CORS headers control which origins a browser permits for cross-origin requests. They don't authenticate or authorize API calls. The Platform's authentication, RBAC, and network policies remain the primary access controls.

Troubleshoot CORS issues​

Browser shows "blocked by CORS policy"​

The ingress didn't return an Access-Control-Allow-Origin header for the requesting origin. Verify the following:

  1. The enable-cors annotation is "true" on the Platform ingress.
  2. The cors-allow-origin value matches the exact origin the browser sends. Scheme, host, and port must all match.
  3. The ingress controller terminates TLS. Check the Platform's TLS configuration.

Limitations​

  • Changes to ingress annotations require a helm upgrade of the Platform to update the ingress resource.