Configuration
betterConsole() config
Section titled “betterConsole() config”The betterConsole() factory accepts a BetterConsoleConfig object:
import { betterConsole } from "@usebetterdev/console";
const consoleInstance = betterConsole({ connectionTokenHash: process.env.BETTER_CONSOLE_TOKEN_HASH!, adapter: drizzleConsoleAdapter(db), // optional for auto-approve sessions: { autoApprove: process.env.NODE_ENV === "development", // or magicLink: { }, // or (upcoming — not yet implemented) // authenticate: async (request) => { ... }, tokenLifetime: "24h", }, allowedOrigins: ["https://console.usebetter.dev"], allowedActions: ["read", "write", "admin"], onError: (error) => console.error(error),});Config reference
Section titled “Config reference”| Option | Type | Default | Description |
|---|---|---|---|
connectionTokenHash | string | (required) | SHA-256 hash of the connection token. Format: sha256:<64 hex chars>. Generated by npx @usebetterdev/console-cli init. |
adapter | ConsoleAdapter | undefined | Database adapter. Required for magic link sessions. Not needed for auto-approve. |
sessions | ConsoleSessionConfig | (required) | At least one session method must be configured. |
sessions.autoApprove | boolean | false | Issue a stateless JWT immediately. Dev only — throws in production. |
sessions.magicLink | MagicLinkConfig | undefined | Enable magic link authentication. Requires adapter. |
sessions.authenticate | (request) => Promise<{email, permissions} | null> | undefined | Custom auth hook for existing auth systems (SSO, OAuth). (upcoming — not yet implemented) |
sessions.tokenLifetime | string | "24h" | Duration string for session tokens. Range: 1h to 7d. Accepts: "1h", "8h", "24h", "30m", "7d". |
allowedOrigins | string[] | ["https://console.usebetter.dev"] | Origins allowed for CORS. The Console UI origin is included by default. |
allowedActions | ConsolePermission[] | ["read", "write", "admin"] | Permission levels granted to sessions. |
onError | (error: unknown) => void | undefined | Called when handleConsoleRequest catches an unexpected error. |
Magic link config
Section titled “Magic link config”| Option | Type | Default | Description |
|---|---|---|---|
allowedEmails | string | string[] | (required) | Email addresses or comma-separated list allowed to authenticate. |
sendMagicLinkEmail | (data: {email, sessionId, code}) => Promise<void> | undefined | Optional — overrides the default Console email relay with your own email sender. When omitted, the code is delivered automatically via console.usebetter.dev. |
maxAttempts | number | 5 | Maximum failed code verification attempts before the magic link is locked out. |
Permissions
Section titled “Permissions”UseBetter Console uses a hierarchical permission model with three levels:
| Level | Includes | Use case |
|---|---|---|
read | Read only | View dashboards, list data |
write | Read + Write | Create, update resources |
admin | Read + Write + Admin | Full access, manage settings |
Higher levels include all lower levels. A session with admin permission can access endpoints requiring read or write.
Configure which permissions sessions receive via allowedActions:
const consoleInstance = betterConsole({ // ... allowedActions: ["read", "write"], // sessions cannot perform admin actions});Product endpoints specify their required permission level:
consoleInstance.registerProduct({ id: "tenant", name: "UseBetter Tenant", endpoints: [ { method: "GET", path: "/tenants", requiredPermission: "read", // any session can access handler: async (req) => ({ status: 200, body: await listTenants() }), }, { method: "DELETE", path: "/tenants/:id", requiredPermission: "admin", // only admin sessions handler: async (req) => { await deleteTenant(req.params.id); return { status: 204, body: null }; }, }, ],});By default, only https://console.usebetter.dev is allowed as a CORS origin. This means only the official Console UI can call your console endpoints from a browser.
To add custom origins (e.g., a self-hosted Console UI or local development):
const consoleInstance = betterConsole({ // ... allowedOrigins: [ "https://console.usebetter.dev", // keep the default "http://localhost:5173", // local dev "https://admin.myapp.com", // custom UI ],});CORS headers are automatically applied to all /.well-known/better/* responses, including OPTIONS preflight requests.
Environment variables
Section titled “Environment variables”| Variable | Required | Description |
|---|---|---|
BETTER_CONSOLE_TOKEN_HASH | Always | SHA-256 hash of the connection token. Format: sha256:<64 hex chars> or bare <64 hex chars>. |
BETTER_CONSOLE_ALLOWED_EMAILS | Magic link mode | Comma-separated admin email addresses allowed to authenticate. |
DATABASE_URL | Magic link mode | Postgres connection string for session and magic link storage. |
Next steps
Section titled “Next steps”- Authentication — auto-approve, magic link, custom auth hook
- Product Registration — expose data to the Console UI
- CLI — all CLI commands