Documentation

AuthForge user guide

Everything you need to run your own identity engine — written for two audiences. If you just want to understand what AuthForge does, start with the Overview. If you run a website and want login today, start with Set up for your website or the setup wizard.

Configuring AuthForge? Enter your domain names and get copy-paste settings — no account required, no coding required.

Website owner

Follow Set up for your website or the setup wizard — plain language, step by step.

Developer

Go to the Quickstart, then JavaScript SDK and the API reference.

Overview

AuthForge answers one question for your application: "who is this user, and what are they allowed to do?" — and it answers it without sending your users' data to anyone else.

Most teams reach for a hosted service like Auth0 or Clerk. Those work, but they bill per user, they keep your identity data on their servers, and every login check makes a round trip to their cloud. AuthForge is the opposite: it is a single program you run on your own server. Your users' accounts, passwords, and sessions stay inside your infrastructure, and verification happens locally — in well under a millisecond.

In one sentence: AuthForge is self-hosted login and access control that you own outright, with bank-grade cryptography built in and no per-user fees.

Set up for your website

This section is for anyone who runs a website and wants login — you do not need to write Rust or read source code.

  1. Choose where AuthForge runs. The easiest path is Ratel (push the repo, attach a domain like auth.yourdomain.com). On your own server, run docker compose up --build.
  2. Open the setup wizard. Type your domain names. Copy the generated environment variables into Ratel or your server.
  3. Test login. Visit https://auth.yourdomain.com/login.html. Create an account or sign in with your workspace credentials.
  4. Add sign-in to your site. Either link to AuthForge (<a href="https://auth.yourdomain.com/login.html">Sign in</a>) or paste the one-line SDK snippet from the wizard into your site header.
  5. Done. Your users sign in through AuthForge; their data stays on your infrastructure. Open the setup wizardWhat's next tab for a printable go-live checklist.
Hand this to your host or developer: send them the link to configure.html — it generates everything they need to paste.

Key concepts

A short glossary so the rest of the guide makes sense — useful whether or not you have a security background.

TermWhat it means
IdentityA user account — the person signing in.
SessionProof that someone signed in successfully, valid for a limited time.
Session token (JWT)A signed, tamper-evident string that carries the session. Your app reads it to know who the user is without asking the database again.
JWKSThe public keys AuthForge publishes so anything can verify a token's signature offline. Served at /api/v1/jwks.json.
Argon2idThe password-hashing algorithm AuthForge uses. Even if your database were stolen, passwords stay protected.
Ed25519The signature algorithm that proves a token came from your server and was not altered.
Organization / tenantA customer workspace. Users belong to one or more organizations with roles and permissions.
Permission / roleWhat a user can do inside an organization (for example billing:read). These travel inside the session token.

Quickstart

You need Docker installed. One command starts Postgres, the identity engine, and the login UI on port 8080.

  1. Start the stack.
    terminal
    git clone https://github.com/techmaster25/AuthForge
    cd AuthForge
    export AUTHFORGE_PASSWORD_PEPPER="$(openssl rand -base64 32)"
    docker compose up --build
  2. Open the login page. Visit http://localhost:8080/login.html and sign in or create an account.
  3. Confirm public keys.
    terminal
    curl http://localhost:8080/api/v1/jwks.json
    # → { "keys": [{ "kty": "OKP", "crv": "Ed25519", ... }] }
  4. Configure for production. Use the setup wizard to generate env vars for your domain.
Tip for non-developers: if a teammate runs the command above on your server, AuthForge is ready. Nothing else needs to be installed, and no account on any third-party service is created.

Configuration

Everything is configured with environment variables. Every value has a safe default, so you can start with none and tune later. The most common settings:

VariableDefaultPurpose
AUTHFORGE_ISSUERhttps://auth.authforge.devThe URL stamped into every token; your edges expect to fetch keys from here.
AUTHFORGE_AUDIENCEauthforgeThe intended consumer of the tokens.
AUTHFORGE_KEY_DIR./secrets/keysWhere signing keys are stored (mount a volume here).
AUTHFORGE_SESSION_TTL_SECS3600How long a session token is valid, in seconds.
AUTHFORGE_PASSWORD_PEPPER(unset)An optional server-held secret mixed into every password hash. Strongly recommended.
AUTHFORGE_ARGON_M_COST19456Argon2 memory cost in KiB (≈19 MiB, the OWASP floor).
AUTHFORGE_MAX_LOGIN_ATTEMPTS10Failed logins before a temporary lockout kicks in.
AUTHFORGE_LOCKOUT_SECS300How long that lockout lasts.
AUTHFORGE_STATIC_DIR./web (auto)Login UI, docs, and SDK files served by the same process.
AUTHFORGE_CORS_ORIGINS(unset = dev)Comma-separated front-end origins allowed to call the API.
AUTHFORGE_DATABASE_URL(unset = memory)PostgreSQL connection string for production persistence.

The full list ships in .env.example in the repository. Use the setup wizard to generate values for your domain.

Verify it works

Three quick checks confirm a healthy deployment:

  • Liveness: curl http://localhost:8080/healthz returns ok.
  • Readiness: curl http://localhost:8080/readyz returns ready.
  • Keys: /api/v1/jwks.json returns one or more Ed25519 keys.

A successful AuthenticateUser call returns a session token plus the user's identity, organizations, and permissions. Passing that token to ValidateSession returns valid: true with the same identity — proof the round trip works end to end.

Integrate your app

The fastest path: add the zero-dependency SDK from your AuthForge host (same origin recommended):

your-site.html
<script src="https://auth.yourdomain.com/sdk/authforge.js"></script>
<script>
  AuthForge.init({ authority: 'https://auth.yourdomain.com' });
  AuthForge.login('user@example.com', 'password').then(function (s) {
    console.log('Signed in as', s.identity.email);
  });
</script>

See the full setup wizard for copy-paste env vars and verification steps.

React apps can wrap the provider when the npm package ships; until then, call the SDK directly:

app.tsx
import { AuthForgeProvider, useAuth } from '@authforge/react';

export function App() {
  return (
    <AuthForgeProvider authority="https://auth.authforge.dev">
      <Dashboard />
    </AuthForgeProvider>
  );
}

function Dashboard() {
  const { user, status } = useAuth();
  if (status === 'authenticating') return <Spinner />;
  return <p>Signed in as {user?.email}</p>;
}

On the back end, you do not need to call AuthForge to check a token — fetch the JWKS once, cache it, and verify the Ed25519 signature locally with any standard JWT library. That is what keeps verification under a millisecond with zero network round trips.

JavaScript SDK

Load /sdk/authforge.js from your AuthForge host. Zero dependencies, works in any HTML page, PHP site, WordPress theme, or SPA.

MethodDescription
AuthForge.init({ authority })Point at your AuthForge URL (defaults to same origin).
AuthForge.login(email, password, org?)Sign in; stores session token; returns session payload.
AuthForge.signup(email, password, org?)Create account and sign in.
AuthForge.me()Current session, or null if signed out.
AuthForge.logout()End session locally and on the server.
AuthForge.getToken()Read the session token (for cross-origin Bearer auth).
AuthForge.jwks()Fetch the public signing keys.

Ready-made login UI: copy login.html and signup.html from the repo, or link directly to them on your AuthForge host. See Brand your login for full white-label options.

Brand your login

AuthForge is headless-first — unlike Clerk or Auth0, there is no hosted dashboard where you drag sliders to recolor a vendor iframe. You own the login experience. That is intentional: your users never see a third-party auth wall, and you are never locked into our UI.

There are three practical paths, from fastest to most control:

ApproachBest forYour brandingAuthForge attribution
1. Link out — send users to https://auth.yourdomain.com/login.htmlFastest setup; no front-end codeReplace the logo and colors in the shipped HTML files on your serverDefault templates show a Secured by AuthForge badge at the bottom of the card (similar to Clerk). Remove it when you fork the templates.
2. Fork the templates — copy login.html, signup.html, and assets/site.css into your site or CDNFull white-label on your domainSwap the logo, wordmark, accent color (--accent in CSS), and page titleDelete the .auth-secured block for a fully unbranded form
3. Build your own UI — use the JavaScript SDK or REST API inside your existing sign-in pageReact, PHP, WordPress, mobile apps100% your design system — AuthForge is invisible to end usersNone — you control every pixel
Environment defaults: set AUTHFORGE_BRAND_NAME, AUTHFORGE_BRAND_LOGO_URL, AUTHFORGE_BRAND_ACCENT, and AUTHFORGE_BRAND_HIDE_SECURED on your server — login pages fetch GET /api/v1/public/branding and apply them automatically. Per-org overrides live in the dashboard theme editor (owners only).

Dashboard theme editor

After sign-in, organization owners on Pro or Enterprise open Login branding on the dashboard. Upload a logo from your computer (PNG, JPEG, WebP, or GIF up to 512 KB) or paste an image URL, set accent color, and optionally hide the Secured by AuthForge badge. Changes are stored per organization and merged over env defaults. Preview with login.html?org=your-slug.

Logo upload API: POST /api/v1/orgs/:slug/theme/logo with { "data_url": "data:image/png;base64,..." }. Uploaded files are served at GET /api/v1/public/org-assets/:slug/logo.

SSO connectors (Google & GitHub)

Login branding (name, logo, colors) is instant — set env vars or use the dashboard theme editor. No Google verification, no multi-day approval like Clerk.

Social sign-in buttons are optional. Paste OAuth client IDs from the setup wizard. Signup OAuth works immediately; login OAuth requires Pro.

OAuth callback URLs (register these in Google Cloud / GitHub):

  • https://auth.yourdomain.com/api/v1/auth/oauth/google/callback
  • https://auth.yourdomain.com/api/v1/auth/oauth/github/callback

Plans & billing

AuthForge uses infrastructure-first pricing. The identity engine itself is free to self-host with unlimited users. You pay us only when you want a commercial relationship — not a per-user tax.

Why would I pay if I self-host?

Self-hosted does not mean unsupported. When you subscribe, you are paying AuthForge (the company) for things the open engine cannot provide on its own:

  • Human support — priority email, guided migrations, and (on higher tiers) SLA-backed response times.
  • Legal & procurement — signed DPA, custom SLA, compliance evidence packs for security reviews.
  • Entitlements in your deployment — your subscription syncs to your account via Stripe. Paid features (for example audit logs) are enforced server-side when your plan qualifies.
  • Roadmap acceleration — SSO connectors, SAML/SCIM, and outbound webhooks are entitlement-gated on paid tiers and ship to subscribers first.

Your end users' credentials and sessions never pass through our servers. We bill for expertise and assurance, not for hosting your identity data.

PlanPriceWhat you get today
CommunityFreeFull engine, unlimited users, login UI, SDK, JWKS, org RBAC, signup OAuth, community support.
ProFrom $79/moLogin SSO, audit logs API, priority email support (48h SLA), guided onboarding. SAML/SCIM and webhooks on roadmap for Pro subscribers.
Enterprise$500/mo or $4,980/yrDedicated architect, signed DPA, air-gapped options, 24/7 SLA, security review support.

Upgrade from the dashboard (Stripe Checkout) or see pricing. Entitlements appear on GET /api/v1/auth/me after checkout completes.

What's live today

We publish this list so marketing and documentation stay honest. If it is not here, it is on the roadmap — not a hidden upsell.

CapabilityStatus
Email + password signup, login, logout, forgot/reset passwordLive
Argon2id password hashing, Ed25519-signed session JWTsLive
JWKS publication and local token verification (<1 ms, no outbound call)Live
Organizations, roles, and permissions inside session tokensLive
Hosted login/signup pages, setup wizard, JavaScript SDKLive
Admin console, plan-gated audit logs APILive
Stripe subscription checkout and webhook entitlement syncLive
gRPC AuthService for trusted internal callersLive
Env-based branding + dashboard theme editorLive
Google / GitHub OAuth (signup free; login SSO requires Pro)Live when OAuth env vars are set
SAML / SCIM provisioningRoadmap — entitlement reserved for Pro+
Outbound lifecycle webhooks to your appRoadmap
WASM edge sidecar, Elixir/Phoenix realtime meshRoadmap
WebAuthn / passkeysRoadmap

Deploy on Ratel

Ratel is the recommended way to put AuthForge online. Push the repo to GitHub, connect Ratel's GitHub App, and create a backend project with internal_port = 8080 and persistent = true.

The server ships the login UI, docs, and API from one process — after deploy, open /login.html on your domain for a live demo. Required secrets:

  • AUTHFORGE_PASSWORD_PEPPER — generate once with openssl rand -base64 32
  • AUTHFORGE_DATABASE_URL — Ratel managed Postgres + ?sslmode=disable
  • AUTHFORGE_CORS_ORIGINS — your front-end domain(s)

Full checklist: Configure AuthForge or RATEL_DEPLOY.md in the repository.

API reference

HTTP — auth (browser-facing)

MethodPathDescription
POST/api/v1/auth/signupCreate account → session token + entitlements
POST/api/v1/auth/loginAuthenticate → session token + entitlements
POST/api/v1/auth/logoutClear session cookie / revoke refresh token
POST/api/v1/auth/forgot-passwordRequest password reset email (always 200)
POST/api/v1/auth/reset-passwordSet new password with reset token
GET/api/v1/public/brandingMerged login branding (?org=slug optional)
GET/api/v1/public/auth-configEnabled OAuth providers + defaults
GET/api/v1/auth/oauth/:provider/startRedirect to Google/GitHub (?mode=login|signup)
GET/api/v1/auth/oauth/:provider/callbackOAuth callback → session cookie → dashboard
GET/PATCH/api/v1/orgs/:slug/themePer-org login theme (owner to PATCH)
GET/api/v1/auth/meCurrent identity, plan, organizations (Bearer or cookie)
GET/api/v1/audit-logsPlan-gated audit history (Pro+)

HTTP — public

MethodPathReturns
GET/api/v1/jwks.jsonThe JWKS (public signing keys).
GET/healthzLiveness probe.
GET/readyzReadiness probe.
POST/api/v1/billing/webhookStripe webhook (signature verified)

HTTP — admin (superadmin only)

MethodPathDescription
GET·POST/api/v1/admin/usersList / create users (paginated)
PATCH·DELETE/api/v1/admin/users/:emailUpdate plan, admin flag, status, or delete
GET/api/v1/admin/auditPlatform audit log (paginated)

gRPC — trusted (local mesh)

Service authforge.auth.v1.AuthService exposes two routes:

  • AuthenticateUser(email, password, organization_context) → a signed session token, a refresh token, expiry, and the resolved identity (user id, organizations, roles, permissions).
  • ValidateSession(session_token) → valid, the resolved identity, and expiry. Pure cryptography — no database touch.

The full contract is the auth_service.proto file in the repository; generate a client in any language with your usual gRPC tooling.

Security & rotation

AuthForge is secure by default. Highlights:

  • Passwords are hashed with Argon2id (tuned to OWASP) and an optional pepper, so a stolen database is not enough to recover them.
  • Sessions are Ed25519-signed and carry expiry, not-before, issuer, and audience — all enforced on validation.
  • Refresh tokens are 256-bit random secrets, stored only as digests and compared in constant time.
  • Brute force is throttled per identity, and unknown-user and bad-password responses are identical to prevent account enumeration.

Key rotation is zero-downtime: drop a new key file into AUTHFORGE_KEY_DIR and point the primary marker at it. The previous key stays in the JWKS until its tokens expire, so nothing signed before the switch breaks.

Testing & hardening

Security claims are only worth what verifies them. AuthForge ships with an automated test suite and a continuous-integration gate:

  • Cryptographic tests — sign/verify round trips, rejection of foreign keys, tampered tokens, expired tokens, wrong audience/issuer, and algorithm-confusion attempts.
  • Credential tests — Argon2id round trips and pepper isolation.
  • Handshake tests — end-to-end authenticate → validate, enumeration resistance, organization-scope enforcement, and brute-force lockout.
  • Supply-chain gate — every change runs cargo‑deny (advisories, licenses, banned and duplicate dependencies, source provenance) and clippy with warnings treated as errors.

See SECURITY.md in the repository for the full threat model and the disclosure process. Found a vulnerability? Follow our responsible-disclosure policy.

FAQ

Do I need a database to try it?

No. The quickstart runs with an in-memory demo store so you can exercise the full flow immediately. For production, connect PostgreSQL.

Where do my users' passwords go?

They are hashed with Argon2id inside your deployment and never leave it. We never see them — there is no AuthForge cloud in the path.

What happens if AuthForge restarts?

Signing keys are persisted to the key volume, so the same keys load on restart and existing sessions keep validating.

Is it really free?

The self-hosted Community tier is free forever, with no per-user fees. Paid tiers add support and enterprise controls — see Pricing.

How do I configure AuthForge for my website?

Open the setup wizard, enter your domain names, and copy the generated settings. The plain-language guide is at Set up for your website.

Can I customize the login page like Clerk?

Yes — three layers: environment variables for deployment-wide defaults, a dashboard theme editor for per-org overrides, or fork login.html / use the SDK for full white-label. See Brand your login.

Why pay for a self-hosted product?

The engine is free. Subscriptions buy support, legal documents, SLA-backed response, and server-side entitlements (like audit logs). See Plans & billing.

Do I need a separate server for the login page?

No. AuthForge serves the login UI, docs, and API from one process on port 8080 — including on Ratel.