V4 design decision: privileges are frozen into the session token until it expires
- Dominant language
- TypeScript
- Stars
- 8
- Forks
- 3
- Avg merge
- 21m
- Merged PRs (30d)
- 3
Description
Found in the v4 security review (2026-09-11).
**Current state.** `isAdmin`, `isPhotographer` and `userId` are derived from the OIDC `groups` claim once, in the `jwt` callback on sign-in, and stored in the JWT. Later requests reuse them. Removing someone from a Kompassi group, or deleting their `User` row, has no effect until the token expires (the Kompassi access token lifetime, at most 10 h). There is no revocation and no "sign out everywhere".
**Options.**
1. Accept the window and document it; 10 h is the upper bound.
2. Re-check periodically: store `groupsCheckedAt` in the token and refresh the flags from Kompassi (userinfo or a refresh token) or from a DB column every N minutes.
3. Keep a `revokedBefore` timestamp per user in the DB and reject tokens issued before it; gives instant revocation and "sign out everywhere" without touching Kompassi.
**Also.** Decryption failures of session cookies (`JWT_SESSION_ERROR`) are currently swallowed in the next-auth logger; they are both the benign expired-token case and the only trace of forged-token probing. Counting them would help whichever option is chosen.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the jwt callback where OIDC groups become session-token flags, then inspect the next-auth logger handling JWT_SESSION_ERROR. Compare the three stated privilege and revocation options, including their effects on Kompassi access, the User row, and token expiry; done requires a decided v4 design and corresponding handling for decryption-failure counts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100