Sessions and logout
Platform sessions live in Postgres, not in a signed cookie. That is what makes them listable and revocable: an administrator can end a session immediately rather than waiting for a token to expire.
The cookie value is stored only as a hash, and is scoped to the tenant host — a session established
on acme.oauth.work belongs to acme.oauth.work.
Self-serve
Section titled “Self-serve”The signed-in user’s own sessions:
GET /sessionsCookie: <tenant session>{ "sessions": [ { "session_id": "sess_…", "amr": ["pwd", "totp"], "ip": "203.0.113.4", "user_agent": "Mozilla/5.0 …", "created_at": 1750000000000, "expires_at": 1752592000000, "current": true } ]}Only live sessions are listed — revoked and expired ones are filtered out. amr shows how each
session was established, so a user can see which of their sessions used a second factor.
POST /sessions/:id/revoke # end one devicePOST /sessions/revoke_others # keep this one, end everything elserevoke_others is the “you left a laptop somewhere” control: it returns the number revoked and
leaves the current session intact.
{ "ok": true, "revoked": 3 }These are same-origin, cookie-backed endpoints — see authentication.
Force logout
Section titled “Force logout”The administrative counterpart, through the management API:
GET /v1/organizations/org_01J…/users/usr_…/sessionsPOST /v1/organizations/org_01J…/users/usr_…/sessions/revokeAuthorization: Bearer sk_live_…This is what you call when an employee is terminated, a device is lost, or an account is suspected compromised. Revocation takes effect on the next request — not at TTL expiry — so a signed-in session stops working immediately rather than lingering for the rest of its lifetime.
SCIM deprovisioning has the same effect: deactivating a user in the customer’s directory kills their sessions on the next request.
Each revocation writes a session_revoked audit event.
Sessions and tokens are different things
Section titled “Sessions and tokens are different things”Revoking a session ends the browser session. It does not, by itself, invalidate access tokens already issued to applications — those are signed JWTs with their own lifetime.
For a complete cut-off:
- Revoke the sessions (above) — stops new authorizations.
- Revoke the tokens — denylists live access tokens and kills refresh tokens.
Access tokens live an hour, so waiting them out is often acceptable. When it is not — a termination, a confirmed compromise — do both.
RP-initiated logout
Section titled “RP-initiated logout”/logout is the OIDC end_session_endpoint and ends one session. See
OIDC for the post-logout redirect rules, which are strict: an unregistered or
unverifiable redirect target is simply not followed.