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, andverificationtables). - 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.
| Engine | Auth schema | Console (apply / reset) | Plan tier |
|---|---|---|---|
| libSQL | Yes | Yes | Free |
| PostgreSQL | Yes | Yes | Free |
| MariaDB | Yes | Yes | Free |
| MySQL | Yes | Yes | Solo |
| SQLite | Yes | Copy SQL only | Free |
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.
- 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.
- 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.
- Methods. Email and password, plus Google and GitHub social sign-in.
- 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.
- 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:
# 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 onlygenerate 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 asnpx 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.
- Open Google Cloud Console, then APIs & Services, then Credentials.
- Create an OAuth 2.0 Client ID (Web application).
- Add the authorized redirect URI:
https://your-app.com/api/auth/callback/google. - Copy the Client ID and Client Secret into
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET.
GitHub
- Open GitHub, then Settings, then Developer settings, then OAuth Apps, then New OAuth App.
- Set the Authorization callback URL to
https://your-app.com/api/auth/callback/github. - Copy the Client ID and generate a Client Secret into
GITHUB_CLIENT_IDandGITHUB_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.
| System | List | Create | Reset password | Disable | Delete | Revoke sessions |
|---|---|---|---|---|---|---|
| Better Auth | Yes | Yes | Yes | Ban | Yes | Yes |
| Supabase GoTrue | Yes | Yes | Yes | Ban | Yes | Yes |
| PayloadCMS | Yes | No | Yes | No | Yes | Yes |
| Generic users + sessions | Yes | No | No | Revoke only | Yes | Yes |
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-authjspreset 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.