Skip to main content

Session policy and sign-out behaviour

How long a session lasts, what ends one, what a user experiences at each boundary, and why suspending an account does not sign anybody out.

Written for whoever runs IT9 min readUpdated

A session is the state that lets somebody keep using the console without typing their password again. Sessions are the part of an identity system people notice only when they are wrong: too short and everyone is irritated all day, too long and a laptop left on a train stays signed in for a fortnight.

This article gives the real numbers, what ends a session, what the person sees at each boundary, and the two administrative actions whose effect on sessions surprises people.

The numbers

The session values in force. The first two rows are fixed platform-wide; the last two are now genuinely set by policy — see the section below, which corrects what this article used to say.
SettingValueWhat it means in practice
Access token lifetime15 minutesThe short-lived credential attached to each request. It is renewed silently in the background; nobody sees this boundary.
Idle timeout30 minutesThirty minutes with no request at all ends the session. Activity is stamped on every authenticated request, so a session in use never idles out.
Refresh token / session lifetime7 days by default, but now genuinely capped shorter by an enforced session-lifetime policy rule — 8 hours on the seeded default policyThe outer limit of a session. A session now actually ends at whichever is shorter: the platform's 7-day ceiling, or your organisation's configured session lifetime.
Concurrent sessions per user5A sixth sign-in displaces the oldest session. Somebody who works across a desktop, a laptop and a phone will not notice; somebody who never closes anything eventually will.

In ordinary use — a working day with lunch in it — the thirty-minute idle timeout is still the boundary you meet most often. But do not assume a session survives to the old seven-day ceiling any more: on a tenant running the seeded default policy, it now ends at eight hours.

Session lifetime and re-authentication are now enforced — this corrects an earlier version of this article

Refresh continues to work as described below, with one addition: a rotation now carries the same lifetime and re-authentication deadline forward, and is refused — the session deleted — once the lineage's own lifetime has been reached, distinct from an ordinary expired or reused refresh token.

What ends a session

Six things, and only one of them is the person choosing to leave.

Signing out
The session is removed. The next request on it fails the session check rather than merely expiring later.
Thirty minutes idle
Checked on every authenticated request. When the last activity is older than the timeout the session is deleted and the request is refused.
The session lifetime elapses
Whichever is shorter: the platform's 7-day ceiling, or your organisation's configured session-lifetime rule (8 hours on the seeded default policy). The refresh credential is refused and the session is deleted rather than merely allowed to expire quietly.
Revoking it
Either the person revoking their own session from their session list, or an administrator revoking somebody else's. Both delete the row, which takes effect on that session's next request.
Being displaced
A sixth concurrent session removes the oldest.
A password change
Changing your own password, or having an administrator reset it, deletes all of that user's sessions. See below.

A person can see and manage their own sessions: each one shows the browser identification, the address it was created from, and when. There is a control to end one and a control to end all of them. An administrator can end every session belonging to another member of the organisation, which requires users:write.

Refresh credentials carry the session identifier alongside the secret, and a refresh credential presented after it has already been used is detected and recorded in the audit log as auth.token_reuse_detected. That is the signature of a stolen credential being replayed, and it is worth an alert rule of your own.

What the person actually experiences

Each boundary, and the exact response behind it. These strings are what somebody scripting against the API will see.
BoundaryWhat the person seesWhat the API returns
Access token expires, 15 minutesNothing. It is renewed in the background.—
Idle for 30 minutesThe next click returns them to the sign-in screen.HTTP 401 with {"error":"session idle timeout"}
Session revoked or already goneThe same — back to the sign-in screen, immediately rather than at the next quarter hour.HTTP 401 with {"error":"session expired"}
Refresh after the session lifetime has elapsed, or with a stale credentialA password prompt.HTTP 401 with invalid or expired refresh token
A malformed refresh credentialThe same.invalid refresh token format

Note that the first two are served as plain text rather than as the structured error shape the rest of the API uses. If you are writing a client, do not assume a 401 from these paths will parse as JSON. It is an inconsistency in our own error handling and it is on the list to fix.

One thing you will not find is a cookie setting. Sessions here are bearer-token based — the credentials are returned in the response body and held by the client — so there is nothing to configure about cookie flags, and a browser's own cookie controls have no effect on how long somebody stays signed in.

Suspending an account does not sign anybody out

The same applies to clearing somebody's second factor: the enrolment goes, the sessions stay. And to a role change — a session issued while somebody held the admin role does not lose its permissions the moment you change the role, because permissions are resolved from the membership on each request but the session itself persists.

The deprovisioning flow has an explicit option to revoke sessions, and you should use it. Read User lifecycle and deprovisioning before you run it, because it has a second effect that surprises people.

  1. Change the account state

    Set the account to locked or suspended, or run the deprovisioning flow. This stops any new sign-in.

  2. Revoke every session

    From the member's record, end all of their sessions. Until you do, an open laptop is still an open laptop.

  3. Revoke or reissue their programmatic credentials

    An API token continues to work independently of any session. See API tokens — and read the warning there about the blast radius of the deprovisioning flow before you use it.

  4. Check the audit trail afterwards

    The status change is recorded as user.status_changed with you named as the actor, and session revocation is recorded separately. That record is what you will want in six months when somebody asks who did what.

Password changes, and what they end

Both routes to a new password end every session the account has. When somebody changes their own password they must supply the current one, and on success all of their sessions are removed so every device signs in again. When an administrator resets somebody else's password the same happens to the target account.

There is a restriction on the administrative reset that catches people out: an administrator cannot use it on their own account. The request is refused. To change your own password, use the ordinary change-password route with your current password. If you have forgotten it, use the account recovery flow — which has its own tight rate limit, described in Password policy and lockout.

Password reuse is checked on both routes and refused with cannot reuse a recent password, and the rejection is audited. That is a deliberate friction point: the most common response to a forced reset is to cycle back to the previous password, which returns the account to exactly the state that prompted the reset.

What to do with all this

  • Treat thirty minutes idle as your effective session length when you write anything down for an auditor. It is the boundary people meet, and it is not configurable today.
  • Pair every account suspension with a session revocation, as one action in your own runbook rather than as two steps somebody may forget under pressure.
  • Watch for auth.token_reuse_detected in your audit log. It has few innocent explanations.
  • A global session lifetime and re-authentication interval are now real controls — see the correction above — but they are set on the global session policy, not per group. If a shorter session for one specific group of people is what you actually need, that finer-grained targeting is not available yet; a session-lifetime rule applies organisation-wide.
  • A bare require_reauth: true with no interval is still inert. If you want re-authentication enforced, give it an actual number.

If a shorter session is a genuine requirement for your organisation, set a session-lifetime rule on the global session policy — it is now enforced, organisation-wide. If what you actually need is a shorter session for one specific group rather than everyone, that finer targeting is not available yet; say so when you talk to us rather than assuming a per-group setting exists.

Was this article wrong?

If a procedure here does not match what you see, or a limit we described has changed, tell us and we will fix the page. Email us about this article, or see how to get help if you need an answer rather than a correction.

Everything in identity and access