Missing Access-Control-Allow-Credentials header on Zero Trust

We have a single page app that has both an app.domain and an api.domain endpoint. This obviously causes issues with CORS and authentication when using Cloudflare Zero Trust if the user is logged in on app, but not on api

CORS settings are enabled as follows

And are sending the x-requested-with: XMLHttpRequest header as detailed in Session management · Cloudflare Zero Trust docs

The problem we have is that the 401 errors we are getting back (due to the user not having a session on api.domain yet) do not include the Access-Control-Allow-Credentials header. As this header is missing the response cannot be accessed, which means it’s not possible to tell if this is a 401 error (due to login being required on zero trust) vs a network failure. We could probably work around this by making a follow up request without cookies, but it seems somewhat clunky.

Is this header supposed to be present, or is there some other way we should be approaching this?

Kevin

1 Like

While navigating through the docs, i found this, it might help
https://developers.cloudflare.com/cloudflare-one/policies/access/cors/

I’ve been wanting to get ReactJS + Django behind Cloudflare Access but so far have been unsuccessful with separate domains and separate Access policies.

Do you have a shared *.domain Access policy or separate api.domain, app.domain ones? I’ve been wondering if a shared wildcard policy could help, but I haven’t experimented yet.

Another approach I’ve thought about is a two-layer login. If app.domain gets a 401 could it redirects to some kind of api.domain/redirect?goto=app/home page that redirects back to the front end, after the Cloudlflare Access login which hopefully requires no user interaction because they’re already signed in to the identity provider. Not sure if the backend would need to forward credentials or something or even if it did if the different JS frontend could properly reuse them.

My third idea is embedding a service token into the Javascript on app.domain. This obviously isn’t as good as user specific Cloudflare Access authentication to api.domain but in my case the backend has its framework (Django) authentication that can be hooked up to the same SSO/IdP (mozilla-django-oidc). Maybe the easy to exfiltrate token is about as insecure as a shared wifi password.

My fourth idea is to go same origin with a reverse proxy like nginx in front of both actual origins.