veryfront/oauth.
The module provides:
- pre-configured providers such as GitHub, Google, Slack, and Notion
- route helpers for init, callback, status, and disconnect
- per-user token storage through a required
getUserIdfunction
Prerequisites
- An app session that lets you identify the signed-in user (
getSessionUserIdin the examples below). - A token store backing
OAuthService(Redis, KV, or your own implementation). - Provider credentials (client id, client secret, callback URL) set as
environment variables. See the matching provider config object in
veryfront/oauth.
Quick setup
Two routes handle the full OAuth flow: redirect to the provider and handle the callback. Both handlers require agetUserId function that returns the
authenticated user’s id from your session; unauthenticated requests receive
a 401.
/api/auth/github to start the flow. After authorization, they’re
redirected back to your callback route. Tokens are stored in that user’s
per-user slot: never in a single shared slot.
Security.getUserIdis required. The init handler rejects any request where it returnsnull,undefined, or an empty string. The user’s id is bound into the OAuth state row and the callback stores tokens keyed by(serviceId, userId), so one user cannot overwrite another user’s tokens by completing an OAuth flow.
Choose a provider
Pre-configured provider exports are available for the supported default end-user integrations: GitHub, Slack, Notion, Figma, Linear, GitLab, Airtable, Asana, Gmail, Google Calendar (calendarConfig), Sheets, Google Drive, Jira,
Confluence, Outlook, Teams, SharePoint, and OneDrive.
Some provider configs are retained for source compatibility but correspond to
feature-gated integrations. They are hidden from the default CLI/MCP/runtime
integration surface unless VERYFRONT_EXPERIMENTAL_INTEGRATIONS enables the
matching integration name (for example, salesforce for salesforceConfig) or
all.
Each provider exports a config object (e.g., githubConfig, gmailConfig).
Use the matching export from
veryfront/oauth as the source of truth
for exact config names.
API setup for OAuth credentials
For each OAuth provider, create an application and configure the callback URL:Google APIs (shared credentials)
Google Calendar, Gmail, Docs, Drive, and Sheets all use the sameGOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET. Register one Google OAuth app and
enable all required APIs in the Cloud Console:
Microsoft APIs (shared credentials)
Outlook, Teams, OneDrive, and SharePoint all useMICROSOFT_CLIENT_ID /
MICROSOFT_CLIENT_SECRET. Register one Azure AD app with the required Microsoft
Graph permissions.
API-key integrations
These integrations use API keys set by the developer in their project environment variables. No OAuth app is needed. Use Integrations for connector setup and keep API-key variables in your deployment environment.Token storage
By default, tokens are stored in memory (lost on restart). For production, implement a persistent store. TheTokenStore interface is keyed by
(serviceId, userId) so each user’s tokens live in their own slot, and OAuth
state rows are consumed atomically (one-shot):
setTokens(serviceId, userId, tokens). If the state row is missing, expired,
forged, or already consumed, the callback returns an error without storing
anything.
Status and disconnect
Check if a user is connected, or disconnect them. These handlers also requiregetUserId so they act on the caller’s own tokens only:
Custom OAuth provider
For providers not included, create your own config:Calling provider APIs on behalf of a user
OAuth service clients (e.g.OAuthService.fetch, OAuthService.getAccessToken)
require the authenticated user’s id so tokens are looked up from that user’s
slot:
Verify it worked
Sign in as a test user, then open the init route in a browser:- Redirects to the provider’s consent screen.
-
Returns to your callback route with
?code=...andstate=.... -
Stores tokens for the signed-in user. Confirm via:
-
Calling
gmail.fetch(userId, ...)(or any provider service) returns the expected provider response without a401.