Browse documentation

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

Bash
cp .env.example .env
openssl rand -hex 32
docker compose up --build -d
curl --fail http://127.0.0.1:3000/health

Set 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:

TypeScript
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,
});
Python
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:

Bash
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:

Bash
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:

Bash
docker compose --profile monitoring up -d

Prometheus 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.