Open-source ยท Self-hosted ยท Zero lock-in

Passwordless auth, built on your domain

Stop sending passwords over email. key-chains.life is a drop-in magic-link + passkey auth layer that runs on your infrastructure. You own the keys. You own the data. Forever.

# 1 โ€” Add to your project
npm install @key-chains/sdk

# 2 โ€” Point it at your domain
export KEY_CHAINS_DOMAIN=auth.myapp.com

# 3 โ€” Send a magic link
await keyChains.sendLink({ email: "user@example.com" })

# 4 โ€” Verify on callback
const session = await keyChains.verify(token)
// โ†’ { userId, email, expiresAt }

# That's it. No cloud vendor. No shared secret DB.

The problem with passwords (and most auth SaaS)

Every major breach starts with stolen credentials. Auth-as-a-service fixes the UX but trades one dependency for another.

๐Ÿ”“

Passwords get leaked

62% of breaches involve stolen credentials. Even bcrypt can't save you from reuse.

๐Ÿ’ธ

Auth SaaS locks you in

Auth0, Clerk, Supabase Auth โ€” great DX, until you hit the pricing wall or sunset notice.

๐Ÿ“ฆ

You don't own your user data

When auth lives in a third-party cloud, your user table is a tenant row โ€” not your asset.

How it works

Three moving parts. All yours.

01

Deploy the auth server

One Docker image or a serverless function on your infra. Stores signing keys and session tokens in your own database.

docker run key-chains/server \ --domain auth.myapp.com \ --db $DATABASE_URL
02

Embed the SDK

A tiny JS/TS SDK handles magic-link generation, passkey registration, and session validation in your existing app.

import { keyChains } from '@key-chains/sdk' const link = await keyChains.sendLink(email)
03

Users authenticate

Email โ†’ click โ†’ done. Or tap a passkey. No passwords created, no secrets stored. Sessions signed with your keys.

// Callback route const { userId } = await keyChains.verify(token) return redirect('/dashboard')

Documentation

Everything you need to go from zero to passwordless.

Quick Start

# Prerequisites: Node 18+, any SQL or Mongo DB

# 1. Install
npm install @key-chains/sdk @key-chains/server

# 2. Configure
export KC_DOMAIN=auth.yourdomain.com
export KC_DB_URL=postgres://user:pass@host/db
export KC_FROM_EMAIL=auth@yourdomain.com

# 3. Run the auth server
npx key-chains-server

# 4. Protect a route (Next.js example)
import { withKeyChains } from '@key-chains/sdk/next'

export default withKeyChains(async (req, res) => {
  // req.session.userId is available here
  res.json({ user: req.session.userId })
})

API Reference

POST/auth/send-link

Send a magic link to an email address. Returns a token ID for polling.

Body / Params
{ "email": "user@example.com" }
Response
{ "tokenId": "tok_xxx", "expiresAt": "..." }
GET/auth/verify?token=<token>

Verify a magic-link token. Returns a signed session JWT.

Body / Params
token (query param)
Response
{ "session": "<jwt>", "userId": "usr_xxx" }
POST/auth/passkey/register

Begin WebAuthn registration ceremony. Returns PublicKeyCredentialCreationOptions.

Body / Params
{ "userId": "usr_xxx" }
Response
PublicKeyCredentialCreationOptions
POST/auth/passkey/authenticate

Complete WebAuthn authentication. Returns signed session JWT.

Body / Params
PublicKeyCredentialAssertionResponse
Response
{ "session": "<jwt>", "userId": "usr_xxx" }
POST/auth/session/revoke

Revoke the current session (logout).

Body / Params
Bearer token in Authorization header
Response
{ "ok": true }

Configuration Reference

VariableRequiredDescription
KC_DOMAINYesYour auth subdomain (e.g. auth.myapp.com)
KC_DB_URLYesPostgres or MongoDB connection string
KC_FROM_EMAILYesSender address for magic links
KC_SMTP_URLYesSMTP connection string (or set KC_SENDGRID_KEY)
KC_JWT_SECRETNoCustom signing secret (auto-generated if unset)
KC_LINK_TTLNoMagic link TTL in seconds (default: 900)
KC_SESSION_TTLNoSession TTL in seconds (default: 2592000)
KC_PASSKEYSNoEnable passkey/WebAuthn support (default: true)
KC_ALLOW_LISTNoComma-separated domains that may sign in

Framework Guides

Next.js (App Router)Coming soon
Next.js (Pages Router)Coming soon
Express / NodeComing soon
RemixComing soon
SvelteKitComing soon
HonoComing soon

Get early access

We're onboarding projects one by one. Drop your email and we'll reach out when we're ready for you.

No spam. Just one email when we're ready.