AUTH4D-122 per-application CORS for guest sign-in

POST /t/{tenantId}/guest now honours each application’s registered Allowed origins, like token, revocation and UserInfo (AUTH4D-63, AUTH4D-85). A web page (browser SDK signInAsGuest() or Unity WebGL) can start a guest session from its own origin without that origin being on the deployment-wide CLIENT_ORIGINS list. This closes the gap left open in AUTH4D-66 and AUTH4D-85.

Preflight

The browser sends a preflight because the request body is JSON. The preflight carries no client_id, so it is answered for an origin registered on any enabled browser application of the active tenant in the path:

OPTIONS {AUTH_ORIGIN}/t/ten_.../guest
Origin: https://game.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://game.example
Vary: Origin
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 600

Any other method or requested header, a non-canonical origin, or an origin the tenant has not registered gets 403 with no CORS headers. No Access-Control-Allow-Credentials is ever sent; the SDK calls the endpoint with credentials: "omit".

Guest request

The guest feature resolves the client_id from the body first, then decides the origin:

Origin header Result
None (servers, native games) Unchanged; no CORS headers
On the deployment-wide list Unchanged; the boundary adds Access-Control-Allow-Origin
One of the named browser client’s origins 200 with Access-Control-Allow-Origin: <origin>, Vary: Origin
Anything else (including a sibling client’s) 403 {"error":"access_denied"} before any guest is created

Errors that occur before the client is resolved (malformed body, unknown or disabled client) are returned without CORS headers to non-deployment origins. Arbitrary origins are never reflected.

The other guest steps (/guest/linking-intent, /guest/upgrade, /guest/upgrade-intent/*) keep the deployment-wide policy; the hosted login calls them from the auth origin.

Tests

  • tests/integration/auth4d-122.guest-cors.test.ts: preflight and POST from a registered origin, sibling and unregistered origins, tenant isolation, disabled applications, requests without an Origin, and the deployment-wide list.
  • tests/integration/auth4d-85.browser-sdk-cors.test.ts now checks the deployment-wide policy on /guest/linking-intent instead of /guest.

Source: docs/api-spec/auth4d-122.md