Skip to content

devops-k8s: Ingress CORS configuration for SSO-integrated services

Purpose: Ensure all services that integrate with SSO have correct CORS at the ingress layer in devops-k8s so browser requests from frontend origins are allowed. Apply these in apps/<app-name>/values.yaml (or equivalent Ingress/Helm templates) in the Bengo-Hub/devops-k8s repo.

Reference values: This repo includes devops-k8s/apps/<app_name>/values.yaml with ingress CORS annotations; copy or merge into your actual devops-k8s repo.

Note: Backend services (auth-api, ordering-backend, etc.) already send CORS headers from application code. Ingress-level CORS can supplement or ensure headers are present when the app is behind a proxy. Prefer keeping app-level CORS as source of truth; use these annotations to align ingress with the same policy or to add CORS when the app does not.


1. Allowed origins (canonical list)

Use this list for both backend env (HTTP_ALLOWED_ORIGINS / app CORS) and ingress annotations where applicable:

Canonical list (matches devops-k8s/apps/*/values.yaml ingress hosts only; no alternate domains):

Origin Service type
https://ordering.codevertexafrica.com Ordering frontend
https://example-tenant.com Cafe website
https://accounts.codevertexafrica.com Auth UI
https://sso.codevertexafrica.com Auth API (SSO)
https://notifications.codevertexafrica.com Notifications UI
https://riderapp.codevertexafrica.com Rider app
https://pricing.codevertexafrica.com Subscriptions UI
https://books.codevertexafrica.com Treasury UI
https://pos.codevertexafrica.com POS UI
https://logistics.codevertexafrica.com Logistics UI
https://inventory.codevertexafrica.com Inventory UI
https://ticketing.codevertexafrica.com Ticketing UI
https://projects.codevertexafrica.com Projects UI
http://localhost:3000 Local dev (cafe, auth-ui, etc.)
http://localhost:3001 Local dev (ordering-frontend)
http://localhost:3002 Local dev (rider-app)
http://127.0.0.1:3000 Local dev
http://127.0.0.1:3001 Local dev

For dynamic allow (any https://*.codevertexafrica.com), use the regex or multi-origin form shown below.


2. NGINX Ingress CORS annotations

If your Ingress uses NGINX Ingress Controller, add these annotations to the backend API Ingress resources (so that browser requests from the frontend origins above are allowed). Frontend apps (Next.js) are same-origin to their own host and do not need ingress CORS for their own domain; they need the backend ingress to allow the frontend origin.

2.1 auth-api (SSO)

Host: sso.codevertexafrica.com
Path in devops-k8s: apps/auth-api/ (or equivalent)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://ordering.codevertexafrica.com, https://example-tenant.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, https://notifications.codevertexafrica.com, https://riderapp.codevertexafrica.com, https://pricing.codevertexafrica.com, https://books.codevertexafrica.com, https://pos.codevertexafrica.com, https://logistics.codevertexafrica.com, https://inventory.codevertexafrica.com, https://ticketing.codevertexafrica.com, https://projects.codevertexafrica.com, http://localhost:3000, http://localhost:3001, http://localhost:3002, http://127.0.0.1:3000, http://127.0.0.1:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Request-ID, X-Requested-With, X-API-Key, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

Important: auth-api must allow X-Tenant-ID so frontends that send the tenant UUID from GET /api/v1/auth/me (e.g. cafe-website, notifications-ui) do not hit CORS preflight failures. Application CORS in auth-api/internal/httpapi/router.go and ingress must both include X-Tenant-ID.

2.2 ordering-backend

Host: orderingapi.codevertexafrica.com
Path in devops-k8s: apps/ordering-backend/ (or apps/ordering-backend/values.yaml under ingress)

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://ordering.codevertexafrica.com, https://example-tenant.com, https://pos.codevertexafrica.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, https://notifications.codevertexafrica.com, https://pricing.codevertexafrica.com, https://books.codevertexafrica.com, https://logistics.codevertexafrica.com, http://localhost:3001, http://127.0.0.1:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Request-ID, X-Tenant-ID, X-Tenant-Slug, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.3 notifications-api

Host: notificationsapi.codevertexafrica.com
Path in devops-k8s: apps/notifications-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://notifications.codevertexafrica.com, https://ordering.codevertexafrica.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, https://pricing.codevertexafrica.com, https://books.codevertexafrica.com, http://localhost:3000, http://localhost:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.4 logistics-api

Host: logisticsapi.codevertexafrica.com
Path in devops-k8s: apps/logistics-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://logistics.codevertexafrica.com, https://riderapp.codevertexafrica.com, https://ordering.codevertexafrica.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, http://localhost:3002, http://localhost:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.5 treasury-api

Host: booksapi.codevertexafrica.com (Treasury UI is at books.codevertexafrica.com)
Path in devops-k8s: apps/treasury-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://books.codevertexafrica.com, https://ordering.codevertexafrica.com, https://example-tenant.com, https://pos.codevertexafrica.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, http://localhost:3011, http://localhost:3001, http://localhost:4201"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.6 inventory-api

Host: inventoryapi.codevertexafrica.com
Path in devops-k8s: apps/inventory-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://ordering.codevertexafrica.com, https://example-tenant.com, https://pos.codevertexafrica.com, https://inventory.codevertexafrica.com, http://localhost:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.7 pos-api

Host: posapi.codevertexafrica.com
Path in devops-k8s: apps/pos-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://pos.codevertexafrica.com, https://ordering.codevertexafrica.com, https://example-tenant.com, http://localhost:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

2.8 subscriptions-api

Host: pricingapi.codevertexafrica.com
Path in devops-k8s: apps/subscriptions-api/

metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://pricing.codevertexafrica.com, https://ordering.codevertexafrica.com, https://accounts.codevertexafrica.com, https://sso.codevertexafrica.com, https://books.codevertexafrica.com, http://localhost:3010, http://localhost:3001"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, PATCH, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-headers: "Accept, Authorization, Content-Type, X-Tenant-Slug, X-Tenant-ID"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-max-age: "300"

3. values.yaml: Backend env (HTTP_ALLOWED_ORIGINS)

For backends that read CORS from env (e.g. ordering-backend HTTP_ALLOWED_ORIGINS), set in values.yaml under the app's env or extraEnv:

App Env var Example value
ordering-backend HTTP_ALLOWED_ORIGINS https://ordering.codevertexafrica.com,https://example-tenant.com,https://pos.codevertexafrica.com,https://notifications.codevertexafrica.com,https://pricing.codevertexafrica.com,https://books.codevertexafrica.com,https://logistics.codevertexafrica.com,https://accounts.codevertexafrica.com,https://sso.codevertexafrica.com,http://localhost:3001,http://127.0.0.1:3001
auth-api (CORS via ingress only) See §2.1; origins = configured frontend hosts from values.yaml
notifications-api (if supported) Same pattern: frontend origins only
logistics-api (if supported) Same pattern
treasury-api (if supported) Same pattern
inventory-api (if supported) Same pattern
pos-api (if supported) Same pattern
subscriptions-api (if supported) Same pattern

4. Frontend apps (no ingress CORS needed for same-origin)

Frontend apps (ordering-frontend, cafe-website, notifications-ui, auth-ui, rider-app, logistics-ui, treasury-ui at books, pos-ui, subscriptions-ui at pricing, inventory-ui, ticketing-ui, projects-ui) are origins that call backends. Their Ingress resources do not need CORS annotations for their own domain; CORS is required on the backend ingress (and app) so that these origins are allowed when the browser sends requests to the API.

Ensure each frontend's build receives the correct production API/SSO URLs (see shared-docs/mvp-critical-path.md §9.2).


5. Checklist (devops-k8s repo)

  • [ ] auth-api ingress: CORS annotations per §2.1
  • [ ] ordering-backend ingress: CORS annotations per §2.2; HTTP_ALLOWED_ORIGINS in values.yaml per §3
  • [ ] notifications-api ingress: CORS annotations per §2.3
  • [ ] logistics-api ingress: CORS annotations per §2.4
  • [ ] treasury-api ingress: CORS annotations per §2.5
  • [ ] inventory-api ingress: CORS annotations per §2.6
  • [ ] pos-api ingress: CORS annotations per §2.7
  • [ ] subscriptions-api ingress: CORS annotations per §2.8
  • [ ] All backend values.yaml: env for CORS/allowed-origins where the app supports it

6. Reference

  • NGINX Ingress CORS: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors
  • Application-level CORS: mvp-critical-path.md §9 (CORS and production domains)