SSO across your apps
Useful if you want to…
give users one login for several applications;
keep the applications untouched: no SDK, no OIDC library, no frontend patch;
share a session between
app.example.com,reports.example.comand similar hosts;revoke a session centrally and have every application refuse it on the next request.
Gate One is a reverse proxy: the application still receives a normal HTTP request. It never sees a token unless you ask for it.
What the user sees
The first visit to any protected host redirects to the login host. After the identity provider callback, Gate One sets one session cookie on the shared parent domain. Every other Gate One route on that domain accepts the same session, so the user does not log in again.
According to the route, the application receives an identity:
X-Gate-One-Subject(opaque, stable per user and issuer) when usage events are enabled;the identity headers configured by the auth provider;
the original
Authorizationheader only when the route explicitly delegates it.
What actually enables SSO
Three things together:
the same authentication provider verifies both routes;
a shared cookie domain (
cookieDomain) covers every application host;both routes are served by the same Gate One deployment.
Adding a second route alone does not create SSO. Replacing the provider alone does not create SSO either. The second application must use the same provider and share the same session cookie domain.
The complete sequence and configuration are in the multi-app SSO example.
Logout and revocation
The RP session lifetime is Gate One’s own (sessionTtlSeconds, one hour
by default), independent of the identity provider’s short ID-token
lifetime. Logout clears the cookie and records the revocation:
RP-initiated logout uses the provider’s
end_session_endpoint;back-channel logout is validated and persisted;
a revoked
sid/subis refused on the next request.
A revocation covers only sessions and tokens issued before it: a new sign-in after a logout is accepted — a user is never locked out by their own logout — while a copied cookie from before the logout still fails.
The revocation TTL defaults to the issuer’s advertised refresh-token lifetime, or 30 days. It is never shorter than the session TTL.
Register the logout redirect at the IdP
RP-initiated logout sends the originating application as
post_logout_redirect_uri. Register every application host as a
valid post-logout redirect URI:
Keycloak: client → Valid post logout redirect URIs, one
https://app.example.com/*per application host;the embedded IAM:
tenants[.postLogoutRedirectUris] (empty falls back toredirectUris, the login host only).
If the IdP rejects that URI it shows an error and does not end its SSO session. Gate One’s own session is gone, but the next visit finds the IdP session and signs the user straight back in — so login looks "refused" even though no error is shown.
Troubleshooting
| Symptom | Cause |
|---|---|
| the application host is not a registered post-logout redirect URI |
signed back in immediately after logout, or login "refused" without an error | the IdP SSO session was not ended because its post-logout redirect was rejected |
"Login session expired" right after returning from the IdP | the sign-in took longer than the transaction window (15 minutes), or a second sign-in in the same browser replaced it |
Operational notes
Same parent domain required.
cookieDomainmust cover every application host.app.company.comandapp.other.comcannot share a cookie. For unrelated domains, use cross-domain SSO: each domain keeps its own cookie and the IdP session provides the single login.Secrets never in the file. Use
clientSecretEnv.Several replicas? See Horizontal scaling for the shared-state requirement.
Important |
|