Authentication
How Selyf authenticates a user with Google, and how its session and CSRF model work.
See Gmail integration for what happens with this access once it is granted, and API Reference for the full request/response contract of every endpoint below.
Flow
A standard OAuth 2.0 Authorization Code flow with Google, requested with access_type=offline and prompt=consent so a refresh token is issued on first connection. Identity is resolved through Google's own userinfo endpoint, not decoded from a locally-verified ID token.
Scopes
Exactly three scopes are requested: openid, email, and the read-only Gmail scope (https://www.googleapis.com/auth/gmail.readonly). Nothing broader is ever requested — Google enforces the read-only boundary at the API level, independent of anything this application chooses to do.
Session
One encrypted, HttpOnly session cookie identifies the signed-in account. It is never readable by client-side JavaScript and is scoped to this application's own origin.
CSRF protection
Every state-changing request (disconnect, account deletion, sync, AI analysis and drafting) must include an X-CSRF-Token header matching the token bound to the current session, and its Origin header must match the web app's own configured origin. This is a separate mechanism from the OAuth state parameter used during the login flow itself.
Rate limiting
Authentication and account-changing endpoints carry a stricter rate limit than the rest of the API, to slow down credential-stuffing and account-enumeration attempts specifically.
Endpoints
/auth/googleRedirects the browser to Google's OAuth consent screen.
/auth/google/callbackGoogle redirects back here after consent. The request state is validated, the authorization code is exchanged, and a session is established.
/auth/sessionReturns whether the current session is authenticated, and if so, a CSRF token and the connected account email.
/auth/logoutClears the current session.
/auth/google/disconnectRevokes Gmail access with Google and clears stored credentials. Requires an authenticated session and a valid CSRF token.
/auth/accountPermanently deletes the account and all associated data. Requires an authenticated session, a valid CSRF token, and a JSON body of { "confirm": true }.