Skip to content

Sessions and SSO

How long people stay signed in, how one sign-in carries across clients, the consent and terms screens, and how sign-out reaches every app.

Every sign-in opens a session: a record on the server, tied to one client and one browser, that every token issued afterwards names. Ending the session stops those tokens on their next use, even if they have not expired. Around that core sit four decisions you make per client: how long sessions last, whether they are shared with other clients, whether the person is asked for consent or to accept terms, and how your apps hear about a sign-out.

Session lifetime and Remember me

How long a session lasts is the client’s session lifetime, which also sets how long its ID tokens are valid:

SettingDefaultAccepted rangeWhere
Session600 minutes (10 hours)1 to 525,600 minutes (one year)Client, Edit, Security, token lifetimes

On the sign-in screen, Remember me decides what happens when the browser closes. Ticked, the session cookie is persistent and survives a browser restart; unticked, it ends when the browser closes.

Single sign-on

With single sign-on, someone who signed in to one client of the realm enters another without typing credentials again. It is opt-in per client and off by default: two apps that happen to share a realm do not share sign-ins unless you say so.

  1. Turn it on for each client that should share

    In Clients, open the client, choose Edit and, in Configuration, under Who may sign in, turn on Single sign-on (SSO). Do it on every client that takes part: a sign-in only carries between clients that both have it on.

  2. Decide whether to always show the account chooser

    Always ask for the account on SSO shows the chooser even when a single account is signed in. Leave it off to enter directly with that account.

Whether a sign-in can be reused is decided again on every request, never from what was true when it was made. It is reused only when:

  • The account is active and not suspended, and its password has not changed since.
  • The account may enter the target client — with Restrict to linked accounts on, it has to be linked to it.
  • The sign-in satisfies the request’s max_age.
  • Nothing the target client requires is missing, such as a second factor it asks for and the original sign-in did not present.

A session opened through single sign-on reports the original sign-in in auth_time, amr and acr, never a fresh one, and always ends with the browser: a Remember me chosen in another app is not inherited.

The account chooser

A browser remembers its recent sign-ins to the realm, forgetting the oldest first. The hosted login shows Choose an account, with Continue as … for each one and Use another account, when:

  • More than one account could enter the client.
  • The request carries prompt=select_account.
  • The client has Always ask for the account on SSO on, unless the request is silent or carries a login_hint.

Silent requests

A request with prompt=none never shows a screen. When it cannot be answered from the existing session, it returns to your redirect URI with an error saying what was missing:

ErrorWhat was missing
login_requiredThere is no reusable sign-in.
account_selection_requiredMore than one account could be used.
interaction_requiredThe person has to answer something first, such as terms or a second factor.
consent_requiredThe client asks for consent that has not been given.

Turn on Ask for consent in the client’s Configuration when the app should ask before receiving the person’s data — typically a third-party app. It is off by default, which suits your own apps.

  • The screen lists the scopes being asked for, with readable names for the standard ones (profile, email, phone, address, offline_access) and your description for custom scopes. The person chooses Allow or Don’t allow.
  • It is shown on the first sign-in and again only when a scope not yet granted is asked for. Consent only grows: a narrower request removes nothing.
  • prompt=consent shows the screen on any client, whatever was granted.
  • Declining records nothing and returns access_denied to the redirect URI.

People see and remove what they granted on the Applications tab of the account pages; removing access also ends their sessions in that app. Administrators find the same list on the user’s Access tab in Users.

Terms of use

  1. Publish the documents and a version

    In the client’s Configuration, under Terms of use, set the Terms of service URL, the Privacy policy URL and the Terms version (up to 64 characters, for example 2026-09). The links open in a new tab from the terms screen.

  2. Turn on the terms step

    In Login layout, switch on terms acceptance. It is always asked right after sign-in, before consent.

The person ticks I have read and accept the terms and chooses Accept and continue, or Decline, which returns access_denied to your app. Each acceptance is recorded with the version, the links shown, the IP address and the browser. Changing the version asks every account to accept again on its next sign-in.

Sign-out

To sign someone out, send the browser to the realm’s end-session endpoint (OpenID Connect RP-Initiated Logout):

ParameterPurpose
id_token_hintThe ID token of the session to end. Required to end anything; an expired token is accepted.
post_logout_redirect_uriWhere to return afterwards. Must exactly match a registered post-logout redirect URI, or a redirect URI when none is registered.
stateReturned unchanged with the redirect.
client_idThe client, when the hint does not already say it.
ui_locales, themeLanguage and palette of the screens shown on the way.
sign-out.tsTypeScript
const ISSUER = 'https://authio.api.hyperio.tech/realms/acme'

export function signOutUrl(idToken: string, state: string): string {
  const url = new URL(ISSUER + '/protocol/openid-connect/logout')
  url.searchParams.set('id_token_hint', idToken)
  url.searchParams.set('post_logout_redirect_uri', 'http://localhost:3000/')
  url.searchParams.set('state', state)

  return url.toString()
}
  • With a valid id_token_hint, the session ends and the browser returns to post_logout_redirect_uri.
  • Without one, nothing ends: the person sees Do you want to sign out? and decides, and the return address is ignored. Any page can link to the endpoint, so a sign-out never happens without proof.
  • A return address that is not registered is not followed: the person stays on You’re signed out, which says the address is not registered.

Telling your apps

A session can end without your app being involved: another app signed out, an administrator ended it, a suspension started. To hear about it, register a logout address in the client’s Configuration:

MechanismHow it worksAddress rules
Back-channel logout URIAuthio posts a signed logout_token from its servers whenever a session of the client ends, for any reason. Failed deliveries are retried for up to 6 attempts, the delay growing up to 6 hours.Absolute https (http only on loopback), no fragment, up to 2,048 characters.
Front-channel logout URIDuring a browser sign-out, Authio loads the address in a hidden frame; Requires the issuer and session ID adds iss and sid to it.Absolute http or https, no fragment, up to 2,048 characters.

The logout token has typ logout+jwt in its header and carries iss, aud, sub, sid, jti and events; it is valid for two minutes. Prefer back-channel when you can: browsers that block third-party cookies can stop a front-channel frame from clearing your cookie.

Ending sessions

What happensWhat ends
Sign-out, an administrator ending a session, refresh token reuseThe session and, if it came from single sign-on, the shared sign-in with every session it opened in other clients.
Your app revokes a token (RFC 7009)Only that client’s session. The shared sign-in stays, so the person can come back through it.
The person removes an app’s access, or loses access to one clientTheir sessions in that client only.
Suspension, deactivation or deletion of the accountEvery session of the account.

Where sessions are seen and ended:

  • The person: the Sessions tab of the account pages, and the Security tab of the Authio app.
  • Administrators: Sessions lists every open session of the realms in scope, with filters, ending in bulk and ending the shared sign-in behind a session; each user’s Activity tab and each client’s Activity tab show theirs.

Sessions live in a store with expiry, so these screens show what is open now. Past sign-ins are in the access log.

Next steps