Documentation
Self-hosting
Run Authlane as one hardened application with PostgreSQL and Redis.
The application container serves the dashboard, hosted connect UI, API, OAuth callbacks, and background workers. A one-shot migration container prepares PostgreSQL.
Prerequisites
Use Node.js 22-compatible images, PostgreSQL 16, Redis 7, a maintained TLS ingress, and independent random values for every secret and keyring.
Implement the workflow
cp .env.example .env
openssl rand -hex 32
docker compose up --build -d
curl --fail http://127.0.0.1:3000/healthSet APP_URL, BETTER_AUTH_URL, and CORS values to exact public HTTPS origins. Keyring entries use
key-id:64-hex-key with the current key first; Better Auth entries use version:secret with the
current version first.
Use DATABASE_URL for the NOBYPASSRLS application role and SYSTEM_DATABASE_URL for the narrowly
granted worker. Keep PostgreSQL and Redis on private networks and require TLS when traffic leaves a
private host.
Point the SDKs at your deployment. Both default to the hosted control plane at
https://app.authlane.io, so this is the one place the option is needed:
import { Authlane } from '@authlane/sdk';
const authlane = new Authlane({
apiKey: process.env.AUTHLANE_API_KEY!,
// Only a self-hosted deployment needs this; the default is https://app.authlane.io.
baseUrl: process.env.AUTHLANE_BASE_URL,
});import os
from authlane import Authlane
with Authlane(
api_key=os.environ["AUTHLANE_API_KEY"],
# Only a self-hosted deployment needs this; the default is https://app.authlane.io.
base_url=os.environ["AUTHLANE_BASE_URL"],
) as authlane:
services = authlane.services.list()Choose an authentication mode
Authlane defaults to AUTHLANE_AUTH_MODE=email-password for backwards-compatible self-hosting and
the local demo. This mode keeps password sign-in, email verification when Resend is configured, and
TOTP for sensitive dashboard changes.
For a passwordless installation, set:
AUTHLANE_AUTH_MODE=magic-link
AUTHLANE_ALLOW_SIGNUP=true
RESEND_API_KEY=<runtime-only Resend sending key>
EMAIL_FROM=Authlane <auth@mail.authlane.io>Production magic-link mode fails at startup when RESEND_API_KEY or EMAIL_FROM is missing. Verify
the sender domain's DKIM and SPF records before switching traffic. Links are single-use, stored only
as hashes, and expire after ten minutes. AUTHLANE_ALLOW_SIGNUP=false lets existing users sign in but
prevents a link from creating a new account.
Never paste a production sending key into source control, build arguments, issue trackers, logs, or chat. If a key is disclosed, revoke it and create a replacement before deployment.
Configure the optional AI Sandbox
The direct tool runner needs no model provider key. To use the production-like Vercel AI SDK agent, set one or more runtime-only provider keys:
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GOOGLE_GENERATIVE_AI_API_KEY=Only organization owners and admins can use Sandbox. Keys stay server-side and the selected model provider receives the ephemeral prompt and any tool context according to its own data policy. See Test connections in Sandbox for the execution boundary and audit behavior.
Optional local monitoring starts with:
docker compose --profile monitoring up -dPrometheus authenticates to /metrics with METRICS_BEARER_TOKEN; Grafana binds to 127.0.0.1 by
default.
Expected result
The migration container exits successfully and one non-root Authlane runtime serves every product surface. PostgreSQL and Redis are not public.
Handle errors
Check migration-role permissions, RLS runtime grants, Redis authentication, exact origin values, and retained keyring versions before changing application code.
Security boundary
Terminate TLS at a maintained ingress, keep the final root filesystem read-only, drop Linux capabilities, and never give the runtime migration privileges.
Next step
Complete security operations and run the performance benchmark.