Files
cfw-auth/docs/better-auth-plugin-compass.md
imeepos e3057928a2 feat: add better authentication features and organization management
- Introduced new database migration for enhanced user and organization management.
- Updated package dependencies to include new Better Auth modules for API keys, Expo, and i18n.
- Implemented SMS functionality for phone verification and password resets.
- Enhanced authentication plugins with username and phone number support.
- Added performance configuration options for session cookie caching and API key updates.
- Updated email templates to include organization invitation messages.
- Improved testing coverage for new features and configurations.
2026-06-10 19:39:15 -07:00

131 lines
6.0 KiB
Markdown

# Better Auth Plugin Compass
This note is the project-level compass for choosing Better Auth plugins. It combines the current official plugin ecosystem, installed package evidence, and `cfw-auth`'s Cloudflare/D1 constraints.
## Source Baseline
- Better Auth official plugin overview, v1.6: `https://better-auth.com/docs/plugins`
- Better Auth plugin mechanism docs: `https://better-auth.com/docs/concepts/plugins`
- Official plugin pages for 2FA, passkey, organization, API key, JWT, Stripe, and community plugins
- Installed package type definitions under `node_modules/better-auth` and `node_modules/@better-auth/*`
- Local runtime config: `src/plugins.ts`
- Local schema-generation config: `src/auth.migration.ts`
Important rule: official docs establish product intent; installed package types establish the exact API shape this repo can compile against.
## Ecosystem Map
| Category | Plugins | Primary use |
| --- | --- | --- |
| Login and identity proof | `twoFactor`, `passkey`, `magicLink`, `emailOTP`, `phoneNumber`, `anonymous`, `username`, `oneTap`, `siwe`, `genericOAuth`, `multiSession`, `lastLoginMethod` | Human authentication, passwordless flows, account recovery, session UX |
| Authorization and management | `admin`, `organization`, `sso`, `scim` | Admin controls, B2B tenants, enterprise SSO, directory sync |
| API, token, and machine access | `agentAuth`, `apiKey`, `jwt`, `bearer`, `oneTimeToken`, `oauthProxy` | API clients, service access, token exchange, agent flows |
| Identity-provider surface | `oauthProvider`, `oidcProvider`, `mcp`, `deviceAuthorization` | Turning the app into an OAuth/OIDC/MCP identity provider |
| Billing and entitlement | `stripe`, `polar`, `autumn`, `creem`, `dodopayments`, `commet` | Subscription, checkout, seats, usage-based pricing |
| Security and operations | `captcha`, `haveIBeenPwned`, `i18n`, `openAPI`, `testUtils` | Abuse prevention, password safety, localized errors, docs, tests |
| Analytics and tracking | `dub` | Lead tracking and OAuth/link attribution |
Community plugins are useful for ecosystem gaps such as LDAP, audit logs, Firebase Auth, payment providers, wallet chains, university email checks, or devtools. Treat them as third-party code: review maintenance, schema changes, runtime compatibility, and test coverage before adopting them.
## `cfw-auth` Current Plugin Set
Default runtime plugins:
- `openAPI`
- `i18n`
- `haveIBeenPwned`
- `emailOTP`
- `twoFactor`
- `multiSession`
- `lastLoginMethod`
- `admin`
- `username`
- `phoneNumber`
- `organization`
- `apiKey`
- `expo`
Conditional runtime plugins:
- `captcha`, when `CAPTCHA_PROVIDER=cloudflare-turnstile` and `CAPTCHA_SECRET_KEY` are set
- `genericOAuth`, when generic OAuth provider env vars are set
- `passkey`, when `PASSKEY_RP_ID`, `PASSKEY_RP_NAME`, and `PASSKEY_ORIGIN` are set
- `jwt`, when `ENABLE_JWT=true`
- `bearer`, when `ENABLE_BEARER=true`
Migration-only static config must include every plugin that can affect schema or generated endpoint metadata. In this repo that means `src/auth.migration.ts` intentionally includes dummy config for conditional plugins. The important schema-bearing addition is `jwt`, which creates the `jwks` table.
## Usage Patterns
Server config:
```ts
import { betterAuth } from "better-auth";
import { i18n } from "@better-auth/i18n";
import { passkey } from "@better-auth/passkey";
import { jwt, organization, twoFactor } from "better-auth/plugins";
export const auth = betterAuth({
database: env.DB,
plugins: [
i18n({
translations: {
en: {},
zh: { USER_NOT_FOUND: "用户不存在。" },
},
detection: ["header", "cookie"],
}),
organization(),
twoFactor(),
passkey(),
jwt(),
],
});
```
Client config, when a plugin exposes a client plugin:
```ts
import { createAuthClient } from "better-auth/client";
import { i18nClient } from "@better-auth/i18n/client";
import { twoFactorClient } from "better-auth/client/plugins";
export const authClient = createAuthClient({
plugins: [
i18nClient(),
twoFactorClient(),
],
});
```
## Best Practices
- Choose plugins from workflow pressure, not from the catalog. Every plugin can add endpoints, hooks, schema, client actions, and security review surface.
- Keep server and client plugin choices paired. Some server plugins need a matching client plugin for typed client actions.
- After changing schema-affecting plugins, run `pnpm db:generate`, inspect SQL, then run `pnpm db:check`.
- Keep conditional runtime plugins represented in `src/auth.migration.ts` when they can affect schema or generated API shape.
- Do not treat `jwt` as a session replacement. Use it for services that need JWT/JWKS, and keep cookie sessions as the normal browser auth path.
- Use `bearer` only for clients that must send bearer tokens to auth endpoints. It widens token-acceptance behavior.
- Keep `captcha` on high-abuse endpoints such as email sign-up, email sign-in, and password reset. Turnstile secrets belong in Worker secrets.
- Keep `genericOAuth` provider config behind env and avoid hard-coding enterprise IdP details.
- Treat `organization` as the tenant boundary. App tables should consume organization/member projections rather than becoming a second source of auth truth.
- Keep API keys hashed, named, prefixed, scoped, and revocable. Organization-owned keys are better for shared integrations.
- Review community plugins like any third-party dependency: schema, hooks, secrets, runtime assumptions, release activity, and tests.
## Simplicity Boundary
The stable core for this project is:
```text
User + Session + Identifier + Organization + Membership + API Key
```
Everything else is an edge capability:
- `captcha`, `haveIBeenPwned`, and `i18n` are auth-flow protection and presentation edges.
- `genericOAuth`, `passkey`, `phoneNumber`, and `emailOTP` are identity proof adapters.
- `jwt`, `bearer`, and `apiKey` are machine/API access edges.
- `expo` is client runtime integration.
Do not move billing, enterprise SSO, SCIM, MCP provider, or OAuth/OIDC provider concerns into the core until a real caller needs them.