@onyx/auth
Better Auth configuration shared by the web app and the CLI.
@onyx/auth packages the Better Auth setup used across Onyx. It covers email + password with verification and reset, organizations with invitations, organization API keys, and the OAuth device flow used by onyx login. Sessions are stored in D1 through the Drizzle adapter. The web app already constructs the server instance and serves it at /api/auth/*, so you only ever call the two APIs below.
Client
@onyx/auth/client exports a ready-made authClient (and its type AuthClient) with the organization and device authorization plugins enabled. This is what components call:
import { authClient } from '@onyx/auth/client';
const { error } = await authClient.signIn.email(value);
const { error } = await authClient.signUp.email(value);
await authClient.organization.create({ name, slug });
await authClient.organization.inviteMember({ email, role: 'member' });
await authClient.organization.setActive({ organizationId });Server
The configured instance is exported as auth from apps/web/src/lib/auth.ts. Server-side code calls the typed API on it directly:
import { auth } from '#/lib/auth';
const session = await auth.api.getSession({ headers: request.headers });
const result = await auth.api.verifyApiKey({ body: { key } });What the instance enables
- Email + password with verification on signup and password reset. All emails go through
@onyx/mail. - Organizations with invitation emails. Invite links point at
{baseURL}/invite/{id}. - Organization-owned API keys (prefix
onyx_) for the public/api/v1surface, sent asx-api-key. - The OAuth device flow (
/deviceverification page) plus bearer token support, so CLIs can authenticate withAuthorization: Bearer <session token>. - A five minute session cookie cache, so
getSessionavoids a D1 query on most requests.
Side effects
Signup enqueues the send-welcome-email job (@onyx/jobs), sending an invitation starts the invitation-reminder workflow (@onyx/workflows), and members joining an organization fan out a member-joined notification (@onyx/notifications). New sessions start with activeOrganizationId set to the user's first organization.
Configuration
| Name | Where | Purpose |
|---|---|---|
BETTER_AUTH_SECRET | .dev.vars locally, Worker secret in production | Signing secret |
BETTER_AUTH_URL | wrangler.jsonc vars | Absolute origin, also used in invite links |
Emails additionally need RESEND_API_KEY and MAIL_FROM; without an API key locally, emails are logged to the console with their action links.