Keepalive via refresh-session; GET pings measured insufficient
The endurance test refuted the sliding-window model I committed earlier. A keepalive doing only GET /api/v3/me succeeded at t+0/30/60/90 and was still rejected by t+120 — consistent with the session ending ~2h after LOGIN (t+107), and inconsistent with 2h after the last request, which would have been t+210. This is a live-vs-source divergence, not a misreading: both the current JwtWhitelistAdapter and the legacy Feathers ensureTokenIsWhitelisted re-set the Valkey TTL on every authenticated request, so the source reads as a sliding window. The instance does not behave that way. So the keepalive now calls POST /authentication/refresh-session, the endpoint behind the UI's "Sitzung verlängern" button, which a separate 100s test showed does hold the reported budget at 7200s. It is the only non-GET request in the server: no body, touches only our own session, cannot read or modify user data, and is not exposed as a tool, so no model-driven call can ever be a POST. It logs the returned budget, which makes a failing extension visible before the session is lost. Whether this is sufficient is NOT established. Two mechanisms still fit: an idle TTL that reads fail to refresh (keepalive works), or an absolute cap/revocation anchored at login — e.g. the IDP's back-channel logout, which clears every token for the account rather than one. Added scripts/session-diagnose.mjs to settle it: it logs the budget every 10 min, so a decaying series indicates the former and an abrupt 401 at 7200s the latter. Docs state the open question rather than asserting a mechanism. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -155,11 +155,12 @@ npm run probe # re-verify the API assumptions
|
||||
`no-new-privileges`, running as the unprivileged `node` user. It writes
|
||||
nothing to disk — downloads are streamed through memory, capped at
|
||||
`MAX_DOWNLOAD_BYTES` (25 MiB default).
|
||||
- **The Schulcloud session dies after 2 hours of inactivity**, so the server
|
||||
pings `/api/v3/me` every 30 minutes to hold it open. This has a consequence
|
||||
worth planning for: **downtime longer than two hours kills the token**, and
|
||||
- **The Schulcloud session ends ~2 hours after login**, and API reads do not
|
||||
extend it, so the server calls `refresh-session` every 30 minutes. Watch for
|
||||
`keepalive: session extended, 7200s` in the logs; a falling budget is the
|
||||
early warning. **Downtime longer than two hours kills the token** and
|
||||
restarting does not recover it — a long power cut means pasting a fresh
|
||||
`TSC_JWT_COOKIE`. The startup log says so immediately. Background in
|
||||
docs/AUTH.md.
|
||||
`TSC_JWT_COOKIE`. Whether the keepalive suffices at all is still being
|
||||
measured; see docs/AUTH.md.
|
||||
- **Monthly chore**: refresh `TSC_JWT_COOKIE` before its 30-day hard expiry.
|
||||
`npm run probe` reports both clocks.
|
||||
|
||||
Reference in New Issue
Block a user