clone

a lazygit-style terminal viewer for openspec repos: watch changes, tasks and spec deltas land as agents work

main
lazyopenspec / testdata / fixture / openspec / changes / harden-session-security / design.md
design.md 2.0K rendered
1## Context23Sessions are opaque ids stored in Postgres (`sessions` table, see add-user-auth). Expiry is enforced only by `last_used_at + timeout`. There is no absolute cap and no user-facing session management. The pentest report (PT-2026-09, finding H-2) recommends idle <= 12h and absolute <= 7d.45## Goals / Non-Goals67**Goals:**8- Meet the pentest recommendation for idle and absolute session lifetime9- Give users self-service revocation of other sessions10- Ship without forcing everyone to log in at deploy time1112**Non-Goals:**13- Device fingerprinting or anomaly detection14- Changing the session id format or cookie attributes15- Admin-initiated revocation of other users' sessions (follow-up)1617## Decisions1819- **Store `absolute_expires_at` instead of deriving from `created_at`**: lets us backfill existing sessions to `now() + 7d` so nobody is logged out on deploy, and leaves room for per-org policies later. Alternative: compute from `created_at` - rejected because it would instantly expire most existing sessions.20- **Revocation deletes the row**: simpler than a `revoked_at` tombstone; audit log already records the event.21- **Drop `remember_me` in two steps**: stop reading it now, drop the column next release, so a rollback does not need a down-migration.2223## Risks / Trade-offs2425- [More frequent logins annoy users] → Ship with in-app notice; measure login volume for two weeks.26- [Backfill touches every session row] → Run in batches of 5,000 during low traffic.27- [Clock skew between app servers] → All comparisons use database `now()`.2829## Migration Plan30311. Deploy migration 0042 (add `absolute_expires_at`, nullable) and backfill.322. Deploy middleware enforcing both timeouts; treat NULL as `created_at + 7d`.333. Next release: make the column NOT NULL and drop `remember_me`.3435Rollback: revert middleware deploy; the extra column is harmless.3637## Open Questions3839- Should revoking the current session from the sessions page log the user out immediately, or require confirmation?