Status: Accepted
Date: 2026-05-03
Deciders: software-architect
Context doc: raxx-app-track-b.md §4
Parent epic: #94
raxx-api-prod (Heroku) already reads FRONTEND_ORIGIN env var to populate flask_cors.CORS(origins=...). The fallback is http://localhost:3000. On production, if FRONTEND_ORIGIN is not set, every cross-origin request from https://raxx.app is rejected by the browser before it reaches Raptor, because the CORS preflight response does not include Access-Control-Allow-Origin: https://raxx.app.
The code is correct. The config-var is missing.
Set FRONTEND_ORIGIN=https://raxx.app on the raxx-api-prod Heroku app.
Set FRONTEND_ORIGIN=https://raxx-app.pages.dev on the raxx-api-staging Heroku app.
No code change is required. The existing CORS init in backend_v2/api/__init__.py handles this correctly via _frontend_origins_raw.split(',').
raxx.app can make cross-origin API calls to api.raxx.app without CORS rejection.supports_credentials=True is already set, which is required for cookie-based session auth across origin boundaries.FRONTEND_ORIGIN on raxx-api-prod immediately opens CORS for that origin. If any other Track B items (CF Access removal, auth flag, env vars) are not also completed, customers will reach a partially-wired API. The rollout plan in Track B §11 gates these steps sequentially to prevent a half-open state from reaching real traffic.origins='*')Rejected. Wildcard CORS is incompatible with supports_credentials=True (browsers reject credentialed requests with a wildcard origin header). It also removes the ability to scope which domains can call the API. The 2026-04-24 security review flagged this as finding C1; it was already fixed.
https://raxx.app in sourceRejected. The FRONTEND_ORIGIN env var pattern is already established and rotatable without redeploy. Putting the origin in source would make staging/prod parity a code branch rather than a config-var difference.
Rejected. CF Access is a surface-gating mechanism, not a browser-facing CORS mechanism. The browser performs CORS preflight before CF Access has any involvement. CF Access cannot substitute for CORS headers.