D18: revise T13.1 to idle timeout + absolute ceiling

Matt asked whether idle time would be a better fit than a flat session
length. It is, but idle-alone weakens D18's own purpose - a continuously
active session would never force a fresh Okta recheck on its own. Decided:
both. AUTH_IDLE_MINUTES (new, default 30) slides the session on activity;
AUTH_SESSION_HOURS (existing var, meaning changes to an absolute ceiling,
default 12 -> proposed 8) caps it regardless of activity.

Docs only in this commit - implementation is T13.1, next.
This commit is contained in:
2026-09-23 11:38:37 -07:00
parent 850b78972b
commit 358469531c
2 changed files with 76 additions and 21 deletions

View File

@@ -259,15 +259,28 @@ the actual code:
signature-verification surface. Traded deliberately: this is
poll-interval-late rather than real-time, which is judged acceptable for an
HR/offboarding-driven event, not a to-the-second requirement.
2. **Also shrink `AUTH_SESSION_HOURS`** as defense in depth, independent of the
sync job, so the already-live-session window itself is smaller regardless
of how fast the sync runs. Proposed default: **2 hours**, down from 12 —
flagged as a recommendation, not confirmed: Okta's own SSO session (set on
the Okta side, separate from this app's cookie) may make re-authentication
silent rather than a real re-login if it outlives this app's shorter
session, in which case 2 hours costs little. Confirm against the tenant's
actual Okta session policy before treating 2 as final; if Okta's SSO
session is itself long-lived, a shorter number here doesn't hurt, either.
2. **Revised 2026-09-23, in response to Matt's question about idle time
instead of a flat session length: sessions now slide on activity, with a
hard ceiling underneath.** A flat `AUTH_SESSION_HOURS` forces a re-check
with Okta on a fixed schedule regardless of activity; a pure idle timer
with no ceiling does the opposite — a continuously-active session would
never force a fresh Okta check on its own, which is a worse fit for the
exact threat this item exists to address (someone still clicking around
after being deprovisioned). Decided: **both**.
- `AUTH_IDLE_MINUTES` (new, default **30**): a session with no request
for this long stops being valid. Implemented as a sliding JWT expiry —
the token is reissued with a fresh `exp` on activity, throttled so the
cookie isn't rewritten on literally every request.
- `AUTH_SESSION_HOURS` (existing var, meaning changes to an **absolute
ceiling**): no session survives past this many hours from the original
sign-in, no matter how continuously active it is. Default changing from
12 to a proposed **8** — flagged as a recommendation, not confirmed.
- Both defaults, and the mechanism itself, should be sanity-checked
against the tenant's actual Okta SSO session policy — if Okta's own
session silently outlives either number, re-authentication here is
likely a fast redirect, not a real re-login screen, so these numbers
cost less than they look like they do. Confirm before treating either
as final.
3. **The sync only ever disables an account — it never re-enables one.** A
rehire showing active in Okta again does not automatically restore access;
an admin re-enabling the account is a deliberate act, consistent with