Cloudflare Access CORS issue

Hi everyone,

my setup is as follows:

SPA on spa.staging.foobar.tld
API on api.staging.foobar.tld

Both domains are protected via Cloudflare Access. Anyone requesting *.staging.foobar.tld needs to sign in via Google to get access.

The SPA requests the API via fetch(“api.staging.foobar.tld”, { method: “POST”, credentials: “include” }). As per https://developers.cloudflare.com/cloudflare-one/policies/zero-trust/cors the Cloudflare Access application is configured to allow credentials, allow all headers, allow all methods, and allow origins “spa.staging.foobar.tld” and “null”.

Visiting spa.staging.foobar.tld will first require Cloudflare authentication, leaving a CF_Authorization cookie for spa.staging.foobar.tld and that works fine.

Visiting spa.staging.foobar.tld also will result in the POST requests mentioned above, for which I’m seeing an OPTIONS preflight with a 200 OK response and the correct access-control-* headers (so far so good).

However, this is then followed by the actual POST request, which results in a 302 redirect to GET https://foobar.cloudflareaccess.com/cdn-cgi/access/login/api.staging.foobar.tld?kid=… which returns the Cloudflare log-in as HTML instead of the API response (in JSON), which naturally breaks my SPA.

Interestingly, visiting api.staging.foobar.tld once (by opening via the browser) stores the CF_Authorization cookie for that domain (api.staging.foobar.tld), and subsequently my SPA will work as long as that cookie is valid.

Looking at https://developers.cloudflare.com/cloudflare-one/policies/zero-trust/cors it seems to suggest that my setup “should just work”. What am I doing wrong?

Thanks in advance
Morris