> ## Documentation Index
> Fetch the complete documentation index at: https://docs.toolshed.philo.ventures/llms.txt
> Use this file to discover all available pages before exploring further.

# Auth Routes

> Better Auth integration for user authentication and OAuth providers.

Toolshed uses [Better Auth](https://better-auth.com) 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 id                              | Mechanism                             | Frontend call                                           |
| ---------------------------------------- | ------------------------------------- | ------------------------------------------------------- |
| `github`, `google`, `slack`, `linear`    | Better Auth **social providers**      | `authClient.signIn.social({ provider, callbackURL })`   |
| `quickbooks`, `gcp`, `docusign`, `carta` | Better Auth **`genericOAuth` plugin** | `authClient.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](/server/connectors) 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](/guides/oauth-setup) for end-to-end provider configuration.
