Skip to main content
Toolshed uses Better Auth for authentication. All auth routes are handled automatically at /api/auth/*.

Authentication methods

Email and password

Better Auth provides built-in email/password registration and login. Users must have a @philo.ventures email domain.

OAuth providers (split into two flows)

Tool providers register with Better Auth via two distinct mechanisms — be careful which API the frontend invokes for each:
Provider idMechanismFrontend call
github, google, slack, linearBetter Auth social providersauthClient.signIn.social({ provider, callbackURL })
quickbooks, gcp, docusign, cartaBetter Auth genericOAuth pluginauthClient.signIn.oauth2({ providerId, callbackURL })
Each provider only registers if both ${UPPER}_CLIENT_ID and ${UPPER}_CLIENT_SECRET are present in env. Missing creds silently drop the provider — the connector availability endpoint exposes which ones are wired up.

Generic OAuth redirect URI

Better Auth’s genericOAuth plugin uses a different callback path than social providers. When registering an OAuth client (e.g. in Google Cloud Console), you must add:
${AUTH_BASE_URL}/api/auth/oauth2/callback/${providerId}
Social providers use ${AUTH_BASE_URL}/api/auth/callback/${provider}. If you reuse the same OAuth client for both flows (e.g. mirroring GOOGLE_CLIENT_ID into GCP_CLIENT_ID), register both redirect URIs.

trustedProviders for account linking

account.accountLinking.enabled: true only allows users to manually link providers. Automatic linking on OAuth sign-in (the typical “user clicks Connect on a Team tool, returns and is logged in to the same account”) requires the provider to be in accountLinking.trustedProviders. Toolshed lists every OAuth provider it ships with as trusted. Without this, a user authenticated via one provider who tries to connect a second hits account_not_linked on the callback.

Session management

Better Auth manages sessions via httpOnly cookies. The web app uses authClient.useSession() to check auth state, and the server validates sessions on protected routes.

API auth middleware

Non-auth routes require either:
  • A valid Better Auth session cookie, or
  • A Bearer token matching TOOLSHED_API_SECRET
The middleware skips auth for /api/health and all /api/mcp/* routes (the latter authenticate via the MCP token in the URL).

Trusted origins

The server accepts requests from localhost:5173 and localhost:5174 by default. Additional origins can be added via the TRUSTED_ORIGINS environment variable (comma-separated). See OAuth Setup for end-to-end provider configuration.