Skip to content
Tarn & Timber Docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

Back-channel logout

How the webshop receives Auth0 back-channel logout and ends its own sessions.

Auth0 is pointed at the webshop through the Terraform variable website_backchannel_logout_url, which must match ^https://[^/?#]+/api/auth0/backchannel-logout$. The API has no receiver.

The Auth0 SDK cookie is the shop’s own session, so the shop is the component that must learn when Auth0 ends one. Auth0 posts a signed logout token to POST /api/auth0/backchannel-logout (src/routes/api.auth0.backchannel-logout.ts, lib/identity/backchannel-logout.ts). The webshop records the revocation in the WEB_SESSION_REVOCATIONS Workers KV namespace, then calls the Auth0 proxy to deny and disconnect grants carrying the verified Auth0 session association. The Shop API has no logout receiver. Independent grants without that association stay connected.

Verifying the token

The receiver accepts one form-encoded token of at most 16 KiB and checks all of the following:

  • RS256 signature against the tenant JWKS, fetched with redirect: manual and a 3 second timeout;
  • issuer https://<AUTH0_DOMAIN>/ and audience equal to the website client;
  • iat, exp, jti and events present, and the token no older than two minutes;
  • the back-channel logout event, a sub or a sid, and no nonce.

A key outage, failed KV write, unresolved legacy sid-only ownership, or incomplete Auth0 proxy cleanup answers 503 so Auth0 retries. Every other failure answers 400. A jti is remembered for 120 seconds once its browser cutoff and Auth0 proxy effects are stored, so a retry of a notification that took effect answers 200 without any further effect, and a retry of one whose write failed applies it.

What is recorded

Token carries Recorded in KV
sid That session id
sub only An account cutoff: every session of the subject signed in up to the notification second

Entries expire after 30 days, the longest session. The cookie records fh_signed_in_at (Unix milliseconds) at the callback, which is what the cutoff compares against. On the next request, resolve() in lib/identity/web.ts refuses a cookie that matches either record.

Linked Poppy grants

The Auth0 proxy durably denies an exact sid before associated grant cleanup. A subject-only notification records a cutoff for linked grants created through that notification second; independent grants without a verified sid stay connected. Verified subject-bearing notifications persist the sid ownership binding. Owned listing also repairs legacy bindings from retained verified grant records before applying display admission, including grants whose sessions are signed out. A sid-only notification without a known subject remains denied and retryable until that trusted recovery resolves it. Bounded cleanup keeps a durable continuation cursor across deliveries; replay completion is never recorded after a failure.

Limits

  • KV is eventually consistent, about 60 seconds across locations, and an isolate caches answers for 5 seconds. A write in the same isolate is visible immediately.
  • An access token already issued to the shop stays valid at the API until it expires. See Customer authority.
  • Poppy writes keep live grant/session checks, reads keep their at-most-five-second authorization cache, and conversations receive sign-out notifications and periodic rechecks. Previously authorized work may finish.
  • A copied cookie is validated only by this revocation list, not by the API.

Sign out everywhere uses the same cutoff; see Account API.

Was this page helpful?