Three layers: a short note at the top, the key lines with our take in the middle, the full source at the bottom.
Migration
0003_sessions.sql
The session-storage migration. How we keep you signed in without keeping anything we shouldn't.
Repo path apps/api/migrations/0003_sessions.sqlLanguage SQL
Short note — more on the way
What this is
The session-storage migration. How we keep you signed in without keeping anything we shouldn't.
What it proves
This file backs one or more of the privacy promises. It is a database migration that lives versioned in the repository. Read the promise →
What to look for in the source below
- Comments and headers that name what each section does.
- File edges: imports at the top, exports or run-blocks at the bottom.
- Any list, configuration, or assertion that looks load-bearing.
Show the full file (42 lines)
41 lines
-- 0003_sessions.sql
--
-- B-priv-1: per-session revocation, JTI tracking, refresh-token model.
--
-- Pre-B-priv-1 the muntin_session cookie was a 14-day bearer JWT
-- with no jti and no server-side store, so:
-- - A rotated JWT_SECRET invalidated every active session.
-- - A leaked token could not be revoked short of secret rotation.
-- - No multi-device hygiene (sign-out elsewhere).
--
-- The new model issues two JWTs at /verify: a 15-minute access JWT
-- and a 30-day refresh JWT. Both carry the same jti, which is the
-- primary key of this table. revoked_at flips to non-NULL on
-- /sign-out or admin revoke; requireAuth + /refresh both check
-- revoked_at IS NULL before honouring a token.
--
-- device_fingerprint is SHA-256(user_agent) -- not IP-tracking,
-- just enough to label "this device's session" in the future
-- /settings/security surface. device_label is human-set when
-- B-gtm-2 (the passcode + "Stay signed in on this phone" toggle)
-- lands.
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY, -- jti
user_id TEXT NOT NULL REFERENCES users(id),
org_id TEXT NOT NULL REFERENCES orgs(id),
kid TEXT NOT NULL, -- JWT key version
device_fingerprint TEXT NOT NULL,
device_label TEXT, -- nullable; set by B-gtm-2
access_expires_at TEXT NOT NULL, -- ISO 8601
refresh_expires_at TEXT NOT NULL, -- ISO 8601
created_at TEXT NOT NULL, -- ISO 8601
revoked_at TEXT, -- ISO 8601 or NULL
revoked_reason TEXT -- 'sign_out' | 'rotation' | 'admin'
);
CREATE INDEX IF NOT EXISTS sessions_user_idx ON sessions(user_id);
CREATE INDEX IF NOT EXISTS sessions_org_idx ON sessions(org_id);
CREATE INDEX IF NOT EXISTS sessions_active_idx
ON sessions(refresh_expires_at)
WHERE revoked_at IS NULL;This is the file as it lives at the moment of this build. The canonical history lives in git. If you want the full history or a specific commit, write to hello@muntin.digital.