Early release, not yet audited

Sign-in for Node.
No dependencies.

Sign-up, sign-in, sessions, and password changes, using only Node's built-in crypto and SQLite. There are no options that turn its protections off.

import { createAuth, createHandler } from "modest-auth";
import { handleNode, toRequest } from "modest-auth";

const auth = createAuth(new DatabaseSync("app.db"));
const handler = createHandler(auth, {
  origin: "https://example.org",
});

createServer(async (req, res) => {
  // Sign-up, sign-in, sign-out, and more, at /auth
  if (await handleNode(handler, req, res)) return;
  const user = handler.userOf(toRequest(req));
  res.end(user ? `Hello, ${user.email}` : "Hello");
}).listen(3000);

Signed in: new session

HttpOnly · Secure · __Host- · SameSite=Lax

Approach

Fewer features, fewer bugs

Many security flaws in authentication come from features and options that combine in ways nobody tested, rather than from the cryptography. modest-auth has few features and no options that weaken it, so there are fewer combinations to get wrong.

Many auth libraries

  • Dozens of packages to install
  • Plugins and database adapters
  • Options that can turn protections off
  • Tens of thousands of lines of code

modest-auth

  • No packages besides itself
  • Node's built-in SQLite only
  • No options that weaken it
  • About 900 lines of code

Signing in

What happens when someone signs in

The routes do all four, so your app doesn't have to.

  1. Where it came fromRequests from other sites are refused.
  2. How many triesAttempts are counted per account, per address, and per IPv6 block, before any password is checked.
  3. The passwordChecked against a scrypt hash. An unknown email takes as long as a wrong password.
  4. The sessionA new 256-bit token replaces any old one, and only its hash is stored.

Features

What's included

Passwords

Hashed with scrypt at OWASP's recommended cost. New passwords follow NIST's rules: at least 15 characters, and not one of 5,500 common passwords.

Sessions

A session lasts 30 days at most, or 7 days unused. Changing the password ends every other session.

Cross-site protection

Changes must come from your own pages, sent as JSON. Signing in always starts a new session, so a cookie set by someone else is never used.

Rate limits

Stored in the database, so restarting the server doesn't reset them.

Routes

Sign up, sign in, sign out, sign out everywhere, change password, delete account, and check the session.

Tests

Each measure in the threat model has a test that fails if it stops working.

$ npm run check
Rules kept: no dependencies; only node: and own imports; source 934 lines.
ℹ pass 84
ℹ fail 0

Compatibility

Runs on Node 24

It also works with any server that uses the standard Request and Response.

  • node:http
  • Express
  • Fastify
  • Bun
  • Deno

Getting started

npm install modest-auth

It's an early release, and hasn't been independently audited. Please don't use it in production until it has.