Skip to content

Configuration

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: {
allowedEmails: "[email protected]",
},
// or (upcoming — not yet implemented)
// authenticate: async (request) => { ... },
tokenLifetime: "24h",
},
allowedOrigins: ["https://console.usebetter.dev"],
allowedActions: ["read", "write", "admin"],
onError: (error) => console.error(error),
});
OptionTypeDefaultDescription
connectionTokenHashstring(required)SHA-256 hash of the connection token. Format: sha256:<64 hex chars>. Generated by npx @usebetterdev/console-cli init.
adapterConsoleAdapterundefinedDatabase adapter. Required for magic link sessions. Not needed for auto-approve.
sessionsConsoleSessionConfig(required)At least one session method must be configured.
sessions.autoApprovebooleanfalseIssue a stateless JWT immediately. Dev only — throws in production.
sessions.magicLinkMagicLinkConfigundefinedEnable magic link authentication. Requires adapter.
sessions.authenticate(request) => Promise<{email, permissions} | null>undefinedCustom auth hook for existing auth systems (SSO, OAuth). (upcoming — not yet implemented)
sessions.tokenLifetimestring"24h"Duration string for session tokens. Range: 1h to 7d. Accepts: "1h", "8h", "24h", "30m", "7d".
allowedOriginsstring[]["https://console.usebetter.dev"]Origins allowed for CORS. The Console UI origin is included by default.
allowedActionsConsolePermission[]["read", "write", "admin"]Permission levels granted to sessions.
onError(error: unknown) => voidundefinedCalled when handleConsoleRequest catches an unexpected error.
OptionTypeDefaultDescription
allowedEmailsstring | string[](required)Email addresses or comma-separated list allowed to authenticate.
sendMagicLinkEmail(data: {email, sessionId, code}) => Promise<void>undefinedOptional — overrides the default Console email relay with your own email sender. When omitted, the code is delivered automatically via console.usebetter.dev.
maxAttemptsnumber5Maximum failed code verification attempts before the magic link is locked out.

UseBetter Console uses a hierarchical permission model with three levels:

LevelIncludesUse case
readRead onlyView dashboards, list data
writeRead + WriteCreate, update resources
adminRead + Write + AdminFull 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.

VariableRequiredDescription
BETTER_CONSOLE_TOKEN_HASHAlwaysSHA-256 hash of the connection token. Format: sha256:<64 hex chars> or bare <64 hex chars>.
BETTER_CONSOLE_ALLOWED_EMAILSMagic link modeComma-separated admin email addresses allowed to authenticate.
DATABASE_URLMagic link modePostgres connection string for session and magic link storage.