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

GET/auth/google

Redirects the browser to Google's OAuth consent screen.

GET/auth/google/callback

Google redirects back here after consent. The request state is validated, the authorization code is exchanged, and a session is established.

GET/auth/session

Returns whether the current session is authenticated, and if so, a CSRF token and the connected account email.

POST/auth/logout

Clears the current session.

POST/auth/google/disconnect

Revokes Gmail access with Google and clears stored credentials. Requires an authenticated session and a valid CSRF token.

DELETE/auth/account

Permanently deletes the account and all associated data. Requires an authenticated session, a valid CSRF token, and a JSON body of { "confirm": true }.