Cross-Domain SSO
Share authentication across multiple domains within the same tenant using a secure bridge/exchange pattern.
Overview
When you have multiple applications on different domains (e.g., app.example.com and blog.example.com), cookies can't be shared between them. ezAuth's SSO bridge solves this by transferring sessions via short-lived, one-time tokens.
Requirement
Both applications must belong to the same tenant in ezAuth. Cross-tenant SSO is not allowed.
How It Works
- User is authenticated on App A (
app.example.com) - User navigates to App B (
blog.example.com) and needs a session there - App B redirects the user to App A's SSO bridge endpoint
- The bridge generates a one-time token (60-second TTL), stores it in Redis, and redirects to App B with the token
- App B exchanges the token for a new session on its domain
Step 1: Bridge (on the source app)
Redirect an authenticated user to the bridge endpoint:
// Redirect to the SSO bridge
const bridgeUrl = 'https://app.example.com/v1/sso/bridge?return_to='
+ encodeURIComponent('https://blog.example.com/sso-callback')
window.location.href = bridgeUrl
The bridge endpoint (GET /v1/sso/bridge):
- Requires an active session (cookie or bearer token)
- Creates a one-time SSO token stored in Redis with a 60-second TTL
- Redirects to
return_towith?__sso_token=<token>appended
Step 2: Exchange (on the target app)
On the target domain's callback page, extract the token and exchange it:
// On blog.example.com/sso-callback
const params = new URLSearchParams(window.location.search)
const ssoToken = params.get('__sso_token')
if (ssoToken) {
const session = await ez.auth.ssoExchange(ssoToken)
// session.access_token, session.refresh_token
// The __session cookie is also set automatically
}
The exchange endpoint (POST /v1/sso/exchange):
- Validates the one-time token from Redis (atomic get + delete)
- Verifies both apps belong to the same tenant
- Creates a new session on the target app's domain
- Sets the
__sessioncookie and returns tokens
Security
- One-time use — tokens are atomically deleted on exchange (Redis pipeline: GET + DELETE)
- Short-lived — tokens expire after 60 seconds
- Tenant isolation — exchange verifies the source and target apps share a tenant
- Token hashing — tokens are stored as SHA-256 hashes in Redis