Security architecture

A closer, more technical look at how Selyf isolates sessions, tokens, and AI requests. For the plain-language version, see the Security page.

Sessions

Sign-in state lives in a single encrypted, HttpOnly cookie (Secure in production, SameSite=Lax) — there is no separate server-side session store to leak. Signing out or disconnecting ends it immediately.

CSRF

State-changing requests (disconnect, account deletion) require a session-bound CSRF token, distinct from the OAuth `state` parameter used during sign-in, compared with a timing-safe check. There’s no independent expiry — the routes that check it also end the session on success, so a token can’t be replayed through the same flow twice.

Two separate Google credentials

The OAuth client used for sign-in and the GCP service account used to receive Gmail push notifications are deliberately different trust domains with different, narrow permissions — mixing them would let a compromise of one impersonate the other.

Token encryption

Your OAuth refresh token is encrypted at rest with AES-256-GCM, using a random initialization vector per encryption operation, before it’s ever written to the database.

IDOR-safe queries

Every repository query that reads a thread, message, or analysis scopes it to the authenticated session’s own user id at the SQL layer — there’s no endpoint parameter that can be swapped to reach another user’s data.

Error handling

Errors are mapped to a closed, documented set of error codes with generic public messages. Internal detail (stack traces, query fragments) never reaches an API response, and structured logs pass through redaction (by key name and by value pattern) before they’re written.

Pull, not push

Gmail notifications are received by this application pulling from a Google Cloud Pub/Sub subscription on an interval, not by exposing an inbound HTTPS webhook. There is no unauthenticated endpoint an attacker could send a forged "new mail" event to.

Looking for the plain-language version? Read Security