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. No Auth0 account, no per-user bill.
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.

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/auth/meCurrent identity, plan, organizations (Bearer or cookie)
GET/api/v1/audit-logsPlan-gated audit history (Business+)

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.

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.