Schema
CREATE TABLE sessions (
token_hash TEXT PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TEXT NOT NULL,
expires_at TEXT NOT NULL
);
Semantics
- Only the hash is stored. The cookie value is never at rest, so a dump of
nx.dbcannot be replayed as a session. - Revocation is a row delete. Sign-out removes the row; nothing has to expire for access to stop.
- Ownership is by
user_id, and the cascade means removing a person removes their live sign-ins in the same statement.
Why not a JWT
A signed token cannot be withdrawn before expiry without a denylist — and a denylist is this table with extra steps. One row per live sign-in is cheaper to reason about.
Rendered from nx-master/data-model/sessions.md · OKF bundle · regenerate with npm run render