Skip to content
Browse docs

Authentication on Layerbase

Layerbase gives you a management layer for auth on a database you own, not a hosted login service. We provision the database, scaffold the auth schema when you ask, and give you a console to see and manage the user rows. The actual sign-in happens in your app, against your database. Layerbase never issues a session, checks a password on a login request, or sits in your auth request path.

If you just want the shortest path on a single engine, the libSQL Auth Server guide is the quickstart. This page is the fuller picture: every supported engine, the wizard, the schema handoff, and what the console can and cannot do for each auth system it detects.

What Layerbase does, and does not do

The line matters, so it is worth stating plainly.

What Layerbase does:

  • Provisions a database and, on request, scaffolds a Better Auth schema on it (the user, session, account, and verification tables).
  • Detects an auth schema that is already there and renders a user console in the dashboard: list users, and (depending on the system) create, reset passwords, disable, delete, and revoke sessions.
  • Generates the wiring you paste into your app: the Better Auth config, the env variable names, and the OAuth redirect URL to register.

What Layerbase does not do:

  • Run a login endpoint. There is no Layerbase-hosted /login, no session issuance, no token minting. Sign-in is code in your app calling Better Auth (or whatever library you use) against the database.
  • Read or store your OAuth client secret. The wizard tells you which env var to put it in; the secret lives in your app environment, never ours.
  • Migrate users between systems. Scaffolding a fresh Better Auth schema does not import users from an existing Supabase GoTrue (or any other) auth schema. The tables and password hash formats differ, so a scaffolded Better Auth server will not recognize accounts created under GoTrue. "Bring your existing users" and "scaffold a new auth server" are two different things; Layerbase does the second, and detects (but does not convert) the first.

Supported engines

Five engines can hold an auth schema. Four of those also support the one-click console actions (probe, apply, reset). SQLite can hold the schema but is copy-SQL only: the hosted embedded engine has no server-side runner, so you apply its schema yourself.

EngineAuth schemaConsole (apply / reset)Plan tier
libSQLYesYesFree
PostgreSQLYesYesFree
MariaDBYesYesFree
MySQLYesYesSolo
SQLiteYesCopy SQL onlyFree

MySQL moved to the Solo plan on 2026-07-01 (its idle footprint, including the ProxySQL pooler, is around 550 MB). MariaDB is wire-compatible with MySQL and stays on the free tier, so it is the free escape hatch if you want a MySQL-family engine without upgrading.

The setup wizard

The wizard lives at /cloud/create/auth and routes you by situation instead of walking a fixed form.

  1. Do you already have a database? If yes, you pick one of your auth-capable databases (libSQL, PostgreSQL, MySQL, MariaDB, or SQLite) and the wizard ends on a screen with the wiring snippets for that engine and a link into the database. If no, it continues.
  2. Just auth, or your entire app? Just-auth recommends libSQL (the lightest option, on the free tier). Entire-app recommends PostgreSQL and shows all five SQL engines. If your plan does not include MySQL, its card is grayed with an inline upgrade path (and the reminder that MariaDB stays free), never hidden.
  3. Methods. Email and password, plus Google and GitHub social sign-in.
  4. Schema (just-auth path). On a console-capable engine you choose between bootstrap and your own migrations (next section). On SQLite the choice collapses to copy-SQL only.
  5. Review. The Better Auth config snippet, the env block, the per-provider OAuth steps, your chosen schema instructions, and, when you are creating a new database, a line disclosing that it uses one of your plan database slots.

When you create a new database, the wizard hands off to the normal Create Database screen with the engine and auth choice preselected.

Bootstrap vs your own migrations

The auth schema is a set of tables. There are two honest ways to get them into the database, and the wizard offers whichever fits.

Bootstrap for you. Create the database with the auth preset, then open its Overview and click Apply. Layerbase runs the scaffolded Better Auth schema for you in one click. This is offered only on the console-capable engines (libSQL, PostgreSQL, MySQL, MariaDB) and only on a database we scaffolded empty for auth (see the established-database rule below). You can optionally seed a starter admin at apply time; the password is hashed once and never stored.

Manage your own migrations. The schema is yours to own. Generate it with the Better Auth CLI and apply it through your project's normal migration tool. The commands differ by ORM:

bash
# Drizzle: generate schema.ts, then push (or generate + run a migration)
npx @better-auth/cli@latest generate
npx drizzle-kit push

# Prisma: generate into prisma/schema.prisma, then migrate
npx @better-auth/cli@latest generate
npx prisma migrate dev

# Kysely or raw SQL: generate schema.sql, then apply it
npx @better-auth/cli@latest generate
npx @better-auth/cli@latest migrate   # built-in Kysely adapter only

generate emits the schema for whichever adapter your Better Auth config uses: Prisma writes prisma/schema.prisma, Drizzle writes a schema.ts, and Kysely writes raw schema.sql. migrate applies the schema directly, but only for the built-in Kysely adapter. Drizzle users run drizzle-kit push (or their migration flow); Prisma users run prisma migrate. Useful flags on both: --output, --config, and --yes.

The CLI is published as @better-auth/cli; recent Better Auth docs also invoke it as npx auth@latest .... Both work today. If one fails, check the Better Auth CLI docs.

For an entire app, your own migrations is the default: an app schema belongs in your migration history. Bootstrap stays available from the Setup panel if you want it later.

Social sign-in: registering an OAuth app

Layerbase generates the redirect URL and the env variable names, and never touches the secret. Better Auth mounts its handler at /api/auth, so the OAuth callback path is /api/auth/callback/<provider>. Register an app with the provider and paste that URL in.

Google

  1. Open Google Cloud Console, then APIs & Services, then Credentials.
  2. Create an OAuth 2.0 Client ID (Web application).
  3. Add the authorized redirect URI: https://your-app.com/api/auth/callback/google.
  4. Copy the Client ID and Client Secret into GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.

GitHub

  1. Open GitHub, then Settings, then Developer settings, then OAuth Apps, then New OAuth App.
  2. Set the Authorization callback URL to https://your-app.com/api/auth/callback/github.
  3. Copy the Client ID and generate a Client Secret into GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET.

Substitute your real app origin for your-app.com. The secrets go in your app environment; Layerbase only shows you where.

Detecting an existing auth system

If a database already has an auth schema (yours, or one a framework created), the console detects it and manages the user rows over read-only fingerprint queries plus dialect-aware writes. It recognizes four systems, and it is honest about the capability differences between them, because what the console can do depends on what the underlying schema supports.

SystemListCreateReset passwordDisableDeleteRevoke sessions
Better AuthYesYesYesBanYesYes
Supabase GoTrueYesYesYesBanYesYes
PayloadCMSYesNoYesNoYesYes
Generic users + sessionsYesNoNoRevoke onlyYesYes

Notes that keep this honest:

  • Better Auth and Supabase GoTrue get full management. GoTrue is detected on PostgreSQL only.
  • PayloadCMS exposes reset (its exact pbkdf2 hashing) and delete, but not create and not a persistent ban.
  • Generic covers a plain users-plus-sessions schema we can read but whose password hashing we cannot verify. The console will list and delete users and revoke their sessions, but it will never write a password hash it cannot prove your app will accept, so create and reset are off.
  • There is no separate Auth.js detection. The historical auth-libsql-authjs preset id is a naming holdover; its scaffolded schema and adapter are Better Auth.

In every case, the console reads and writes user rows. It does not run sign-in for you.

The established-database rule

One-click Apply is offered only on a database Layerbase scaffolded empty for auth. On a database that already has its own schema, apply is disabled (grayed, not hidden) with a note explaining why, and you copy the SQL and run it through your own migrations or the query console instead.

The reason is safety: Layerbase never runs schema-creating DDL against tables it did not create. Blindly applying an auth schema onto a database that already has one (or has unrelated tables) risks colliding with or clobbering data we do not own. So the rule is simple: we bootstrap what we scaffolded, and hand you the SQL for everything else.

An auth database is a normal database

A database you create for auth is a normal database and counts as one slot against your plan limit, the same as any other. The wizard shows your current usage on the review step before you create one. Plan limits today are two databases on Free, one on Solo, and ten on Pro. If you set auth up on a database you already have, nothing new is counted.

Where to go next

  • libSQL Auth Server setup - the single-engine quickstart, with the copy-paste Better Auth, Auth.js, raw, and Python recipes.
  • Better Auth documentation - the library Layerbase scaffolds against.
  • Support - if the console detects your schema wrong or you want an engine or system we do not list yet.