Single Logout

End a user's Hawcx session and propagate the logout to every application in the identity domain via OIDC Back-Channel Logout.

Because every app in a project shares one SSO session, logging out needs to do two things: end that session at Hawcx, and tell the other apps to end their local sessions too. Hawcx implements both with standard OIDC:

Scope

Hawcx supports RP-Initiated Logout and Back-Channel Logout for OIDC. Front-Channel Logout and the OIDC Session Management iframe are not supported. SAML federation does not provide Single Logout.

RP-Initiated Logout

Redirect the browser to the end-session endpoint:

https://api.hawcx.com/oauth2/end_session
  ?client_id=acme-web
  &id_token_hint=<the user's ID token>
  &post_logout_redirect_uri=https://app.acme.com/goodbye
  &state=<opaque>
  &logout_scope=global
ParameterRequiredNotes
client_idYesThe initiating client.
id_token_hintRecommendedThe ID token from sign-in; identifies the session to end.
post_logout_redirect_uriNoMust be registered in the client's post-logout redirect URIs. Exact-match.
stateNoEchoed back on the redirect.
logout_scopeNoglobal (default) ends all of the user's sessions; session ends only the current one.

Hawcx ends the session(s), fans out Back-Channel Logout tokens, clears its SSO cookie, and then redirects to post_logout_redirect_uri (or shows a "logged out" page if none was supplied). An unregistered post_logout_redirect_uri is rejected with an error page; the browser is never redirected to an unvetted URL.

Back-Channel Logout

To receive logout notifications, register a back-channel logout URI for your client in the Settings → OAuth tab. When any app in the domain triggers logout, Hawcx POSTs a signed logout_token to that URI for every joined client.

Loading diagram...

The request is application/x-www-form-urlencoded with a single logout_token field, a Security Event Token (RFC 8417) JWS with typ: secevent+jwt:

{
  "iss": "https://api.hawcx.com",
  "aud": "acme-web",
  "iat": 1717000000,
  "jti": "<unique>",
  "sub": "<user id>",
  "sid": "<session id>",
  "events": { "http://schemas.openid.net/event/backchannel-logout": {} }
}

Implementing your endpoint

Verify the token. Validate the JWS signature against the JWKS, check iss matches the issuer and aud matches your client_id, iat is recent, and the events claim contains the backchannel-logout member. Reject the token if it contains a nonce claim (per the spec, a logout token must not).

Prevent replay. Reject a jti you have seen recently.

End the session(s). If sid is present (a session-scope logout), end the specific session that ID token was issued for. If sid is absent (a global logout), end all of that sub's sessions in your app.

Respond with the correct status and Cache-Control: no-store. Do not redirect.

OutcomeResponse
Session ended (or already gone)200 OK
Token invalid, expired, or replayed400 Bad Request

Delivery is best-effort

Back-Channel delivery has a short timeout and is not retried; a successful end_session does not guarantee every POST landed. Treat back-channel logout as prompt propagation, and rely on your own session lifetime as the backstop.

Correlate the sid claim from Back-Channel Logout with the sid in the ID token you received at sign-in to map a logout to a specific local session.

The require-sid toggle

Each client has a Require sid in logout token setting (backchannel_logout_session_required, default on) in the Settings → OAuth tab:

  • On (recommended): every logout_token includes a sid, so you can end the exact session that ID token belonged to. This is what enables logout_scope=session and lets you correlate a logout with a specific local session.
  • Off: logout tokens may omit sid. Your endpoint then can't distinguish sessions, so treat every notification as a global logout and end all of that sub's sessions.

Leave it on unless your app genuinely cannot track sessions per sid.

Testing

The Settings → OAuth tab includes a Test logout action for each client with a back-channel URI configured. It sends a throwaway, clearly-marked logout_token to your endpoint and reports the HTTP status and latency, useful for verifying reachability and your validation logic without ending a real session.

Session lifetime

Even without an explicit logout, the shared SSO session expires on its own. The lifetime is set per project under Settings → OAuth → Session policy:

SettingDefaultMeaning
Idle timeout30 minutesSliding window; refreshed on each use.
Maximum session length8 hoursAbsolute cap from the time of authentication.

Next steps