Esta página se muestra en inglés. Una traducción al español está en curso.
ScriptsMay 11, 2026·4 min de lectura

OpenAuth — Universal Auth Server You Can Self-Host

Dax Raad's team's centralized auth server you self-host. Multi-tenant, OAuth/password/SAML/passkey. Auth0/Clerk replacement with full control.

SST
SST · Community
Listo para agents

Staging seguro para este activo

Este activo primero queda en staging. El prompt copiado pide inspeccionar los archivos staged antes de activar scripts, config MCP o config global.

Stage only · 29/100Política: staging
Superficie agent
Cualquier agent MCP/CLI
Tipo
Skill
Instalación
Stage only
Confianza
Confianza: Community
Entrada
Asset
Comando de staging seguro
npx -y tokrepo@latest install 4ef9462d-c757-48ec-93c1-db0c2835dc0c --target codex

Primero deja archivos en staging; la activación requiere revisar el README y el plan staged.

Introducción

OpenAuth is a centralized auth server from Dax Raad's team (SST / Toolbeam) — self-host one OpenAuth server that issues OAuth-compatible tokens to all your apps, no matter what auth method (password, OAuth provider, SAML, passkey, magic link). Standards-based, multi-tenant, zero-vendor-lock-in alternative to Auth0/Clerk. Best for: side projects scaling to multiple apps, teams burned by Auth0 pricing tiers, anyone wanting full control over the user database. Works with: any web framework — TS, Python, Go, Rust, PHP. Setup time: 15 minutes.


Server (TypeScript example)

import { issuer } from "@openauthjs/openauth";
import { PasswordProvider } from "@openauthjs/openauth/provider/password";
import { GithubProvider } from "@openauthjs/openauth/provider/github";
import { CodeUI } from "@openauthjs/openauth/ui/code";
import { PasswordUI } from "@openauthjs/openauth/ui/password";

const auth = issuer({
  storage: { type: "dynamo", table: "openauth" },
  providers: {
    password: PasswordProvider(PasswordUI({ /* email + password UI */ })),
    github: GithubProvider({
      clientID: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      scopes: ["user:email"],
    }),
  },
  success: async (ctx, value) => {
    return ctx.subject("user", {
      id: value.email || value.clientID + ":" + value.id,
    });
  },
});

export const handler = auth.handler;   // mount on AWS Lambda / Vercel Functions

Client app (any framework)

import { createClient } from "@openauthjs/openauth/client";

const client = createClient({
  clientID: "my-app",
  issuer: "https://auth.example.com",
});

// Redirect to login
window.location.href = await client.authorize(
  "https://my-app.com/callback",
  "code"
);

// On callback
const tokens = await client.exchange(code, "https://my-app.com/callback");
// tokens.access, tokens.refresh — standard OAuth, use anywhere

Why OpenAuth vs Auth0/Clerk

Need OpenAuth Auth0 Clerk
Self-host Yes No (Private Cloud add-on $$$) No
Pricing Free (your infra) $-$$$$ per MAU Per MAU
Multi-tenant Built-in Yes Yes
Standards-based OAuth/OIDC native OAuth/OIDC Proprietary + OIDC
Storage Postgres / DynamoDB / Cloudflare KV Theirs Theirs
Lock-in None (your DB) Vendor Vendor

Production checklist

  • HTTPS only (issuer redirects break on HTTP)
  • Rotate signing keys every 90 days (auth.rotate())
  • Set short-lived access tokens (15 min) + long refresh (30 days)
  • Use Cloudflare KV or DynamoDB for global edge latency

FAQ

Q: Is it production-ready? A: Yes — Toolbeam runs it in production, several Anthropic-adjacent projects use it. Still v1.x so breaking changes possible. Pin a version and test upgrades.

Q: Storage options? A: Built-in adapters for DynamoDB (recommended for AWS-native), Cloudflare KV (edge-friendly), Postgres (self-host shops), and in-memory for tests. Custom adapter is a ~50-line file.

Q: How does it compare to Lucia / NextAuth? A: Lucia/NextAuth are libraries embedded in your app. OpenAuth is a separate centralized server — preferred when you have 3+ apps sharing users. For one app, NextAuth is simpler. For an org with many apps, OpenAuth is the cleaner architecture.


Quick Use

  1. npm install @openauthjs/openauth
  2. Author issuer({providers, success}) and deploy to Lambda / Vercel Functions
  3. Client app uses createClient().authorize(...) for OAuth flow

Intro

OpenAuth is a centralized auth server from Dax Raad's team (SST / Toolbeam) — self-host one OpenAuth server that issues OAuth-compatible tokens to all your apps, no matter what auth method (password, OAuth provider, SAML, passkey, magic link). Standards-based, multi-tenant, zero-vendor-lock-in alternative to Auth0/Clerk. Best for: side projects scaling to multiple apps, teams burned by Auth0 pricing tiers, anyone wanting full control over the user database. Works with: any web framework — TS, Python, Go, Rust, PHP. Setup time: 15 minutes.


Server (TypeScript example)

import { issuer } from "@openauthjs/openauth";
import { PasswordProvider } from "@openauthjs/openauth/provider/password";
import { GithubProvider } from "@openauthjs/openauth/provider/github";
import { CodeUI } from "@openauthjs/openauth/ui/code";
import { PasswordUI } from "@openauthjs/openauth/ui/password";

const auth = issuer({
  storage: { type: "dynamo", table: "openauth" },
  providers: {
    password: PasswordProvider(PasswordUI({ /* email + password UI */ })),
    github: GithubProvider({
      clientID: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      scopes: ["user:email"],
    }),
  },
  success: async (ctx, value) => {
    return ctx.subject("user", {
      id: value.email || value.clientID + ":" + value.id,
    });
  },
});

export const handler = auth.handler;   // mount on AWS Lambda / Vercel Functions

Client app (any framework)

import { createClient } from "@openauthjs/openauth/client";

const client = createClient({
  clientID: "my-app",
  issuer: "https://auth.example.com",
});

// Redirect to login
window.location.href = await client.authorize(
  "https://my-app.com/callback",
  "code"
);

// On callback
const tokens = await client.exchange(code, "https://my-app.com/callback");
// tokens.access, tokens.refresh — standard OAuth, use anywhere

Why OpenAuth vs Auth0/Clerk

Need OpenAuth Auth0 Clerk
Self-host Yes No (Private Cloud add-on $$$) No
Pricing Free (your infra) $-$$$$ per MAU Per MAU
Multi-tenant Built-in Yes Yes
Standards-based OAuth/OIDC native OAuth/OIDC Proprietary + OIDC
Storage Postgres / DynamoDB / Cloudflare KV Theirs Theirs
Lock-in None (your DB) Vendor Vendor

Production checklist

  • HTTPS only (issuer redirects break on HTTP)
  • Rotate signing keys every 90 days (auth.rotate())
  • Set short-lived access tokens (15 min) + long refresh (30 days)
  • Use Cloudflare KV or DynamoDB for global edge latency

FAQ

Q: Is it production-ready? A: Yes — Toolbeam runs it in production, several Anthropic-adjacent projects use it. Still v1.x so breaking changes possible. Pin a version and test upgrades.

Q: Storage options? A: Built-in adapters for DynamoDB (recommended for AWS-native), Cloudflare KV (edge-friendly), Postgres (self-host shops), and in-memory for tests. Custom adapter is a ~50-line file.

Q: How does it compare to Lucia / NextAuth? A: Lucia/NextAuth are libraries embedded in your app. OpenAuth is a separate centralized server — preferred when you have 3+ apps sharing users. For one app, NextAuth is simpler. For an org with many apps, OpenAuth is the cleaner architecture.


Source & Thanks

Built by Toolbeam (Dax Raad's team). Licensed under MIT.

toolbeam/openauth — ⭐ 2,800+

🙏

Fuente y agradecimientos

Built by Toolbeam (Dax Raad's team). Licensed under MIT.

toolbeam/openauth — ⭐ 2,800+

Discusión

Inicia sesión para unirte a la discusión.
Aún no hay comentarios. Sé el primero en compartir tus ideas.

Activos relacionados