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
- 0runtime dependencies
- ~900lines of source
- 7routes
- 1SQLite database
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.
- Where it came fromRequests from other sites are refused.
- How many triesAttempts are counted per account, per address, and per IPv6 block, before any password is checked.
- The passwordChecked against a scrypt hash. An unknown email takes as long as a wrong password.
- 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.