Cross-Domain SSO

Brand A storefront · token-session-explainer-demo.vercel.app

Brand A

Sign in here first. This app authenticates against the tenant's default domain, idp-aquamarine-damselfly-66200.cic-demo-platform.auth0app.com — a different Auth0 domain than Brand B.

Sign in to Brand A
Security Implications

Strengths

  • Bridges two genuinely different origins (different domains, same tenant) via a Session Transfer Token instead of relying on third-party cookies, which browsers increasingly block by default.
  • The prompt=none silent-SSO check demonstrates the correct failure mode across domains (login_required) rather than a broken 500.
  • IP-bound device binding (enforce_device_binding: 'ip') is live on Brand A despite the mint call running server-side (Vercel serverless) rather than in the browser — confirmed working by enabling "Trust Token Endpoint IP Header" (Advanced Settings → OAuth) on the minting client and forwarding the real end-user IP via the auth0-forwarded-for header. This is also the first confirmation that the mechanism works for the refresh_token exchange grant, not just the Client Credentials Grant that Auth0's own docs explicitly cover.

Risks & Considerations

  • Same STT-audience-confusion class of risk as native-to-web — a token minted for Brand A being redeemable against Brand B's audience would be a cross-tenant-boundary bypass.
  • A verified custom domain (Brand B) and the default tenant domain (Brand A) look identical to an end user; phishing risk increases if users can't tell which is legitimate.
  • The dashboard control for enforce_device_binding sits behind a "Native to Web SSO Methods" checkbox (Cookie or Query Authentication) that must be enabled for the radio group to unlock at all — on Brand A that meant also enabling Query Authentication, which lets Brand A itself accept an inbound session_transfer_token via query string, a capability nothing in this flow actually uses. Harmless while nothing mints a token targeting Brand A's audience, but it's a capability grant that arrived as a side effect of a dashboard UI gate, not a deliberate decision — worth remembering if this pattern is copied into a real deployment.

Hardening Checklist

  • Scope every STT to the exact target audience/domain it was minted for.
  • Monitor and alert on failed silent-SSO checks that don't match the expected login_required pattern — that's a signal something is misconfigured or being probed.
  • If cloning this pattern, verify "Trust Token Endpoint IP Header" is enabled on whichever client mints the STT — without it, Auth0 silently ignores auth0-forwarded-for and binds to the raw connection IP, which is a server IP for any server-mediated exchange like this one.