npm.io
0.4.0 • Published 2d ago

auth-mini

Licence
MIT
Version
0.4.0
Deps
0
Size
256 kB
Vulns
0
Weekly
0
Stars
3

auth-mini

Authentication is a critical subsystem to prove who users are, while Authorization is another critical subsystem to control what users can do.

Minimal, opinionated authentication server for apps that just need a solid authentication core.

Live demo | Docs | GitHub

Good fit for authentication system needs:

  • Password-less Authentication
    • Email One-Time Password (OTP) sign-in
    • Passkey (WebAuthn) sign-in
    • Ed25519 (EdDSA) sign-in for non-browser clients without WebAuthn support
  • Session Management
    • Issue JSON Web Token (JWT) access tokens for backend stateless verification
    • CURRENT/STANDBY JWKS key pairs for smooth key rotation
    • Issue opaque refresh tokens for long-term sessions and easy revocation while keeping JWTs short-lived
  • You control the server and data. Not Google. Not AWS. Not Auth0. You.
    • Simple SQLite storage without extra Database servers (no Postgres, MySQL, Redis, etc. required)
    • Wildcard CORS (Access-Control-Allow-Origin: *) for cross-origin front-ends.
  • UUID-based user ID keeps it simple and opaque, and could be foreign keys for your app's user records if you want.

Not trying to include: (But you can build these on top if you want!)

  • Authorization features like ACLs, RBAC, ABAC, roles, permissions, groups, etc.
  • Social Login like "Sign in with Google/Facebook/GitHub/etc."
  • SMS or TOTP 2FA factors.
  • User profiles like names, avatars, bios, etc.
  • User management features like admin dashboards, user search etc.

OIDC positioning

Auth Mini Core is not an OIDC Provider. Its core goal is brand-owned identity across apps under the same brand, while keeping the authentication model simple.

OIDC has ecosystem value, especially for existing applications that only integrate through OIDC. But it also brings significant protocol and concept complexity, so it should not define or pollute Auth Mini Core. Apps built with Auth Mini in mind should use the native HTTP API or SDKs instead of OIDC.

If OIDC compatibility is needed, the intended direction is an optional bridge or adapter layer that translates OIDC flows to Auth Mini Core. Auth Mini Core should not need to understand OIDC or OAuth concepts such as client_id, scope, authorization_code, id_token, or grant_type.

Main user journeys

Email OTP sign-in
sequenceDiagram
    autonumber
    actor User
    participant Frontend
    participant Auth as Auth Mini Server

    User->>Frontend: Enter email and request sign-in
    Frontend->>Auth: POST /email/start
    Auth-->>User: Send OTP email
    User->>Frontend: Enter OTP
    Frontend->>Auth: POST /email/verify
    Auth-->>Frontend: session_id + access token + refresh token

The downstream Browser and Device high-level SDKs expose sign-in, session, and refresh lifecycle APIs; they do not provide sdk.me.fetch(). GET /me remains a self-audience profile and account-management capability for Auth Mini's own server-side GUI. The low-level auth-mini/sdk/api client retains sdk.me.get() for callers with an appropriate self-audience token.

Passkey registration and sign-in
sequenceDiagram
    autonumber
    actor User
    participant Frontend
    participant Auth as Auth Mini Server

    Note over User,Auth: Register passkey after email, passkey, or eligible Ed25519 sign-in
    Frontend->>Auth: POST /webauthn/register/options
    Auth-->>Frontend: request_id + publicKey
    Frontend->>User: Browser shows passkey creation prompt
    User-->>Frontend: Approve with authenticator
    Frontend->>Auth: POST /webauthn/register/verify
    Auth-->>Frontend: Credential saved

    Note over User,Auth: Later sign in with a discoverable passkey
    Frontend->>Auth: POST /webauthn/authenticate/options
    Auth-->>Frontend: request_id + publicKey
    Frontend->>User: Browser/OS shows available passkeys
    User-->>Frontend: Choose passkey and approve
    Frontend->>Auth: POST /webauthn/authenticate/verify
    Auth-->>Frontend: session_id + access token + refresh token
Device sign-in with Ed25519 keys
sequenceDiagram
    autonumber
    actor User
    participant Device
    participant Auth as Auth Mini Server

    Note over User,Device: User may generate an Ed25519 key pair and keep the private key on the device
    Note over User,Auth: While already signed in via email OTP or passkey
    Device->>Auth: POST /ed25519/credentials (public_key)
    Auth-->>Device: credential_id

    Note over Device,Auth: Later sign in with the saved private key + credential_id
    Device->>Auth: POST /ed25519/start
    Auth-->>Device: request_id + challenge
    Device->>Device: Sign challenge with saved private key
    Device->>Auth: Complete auth flow with request_id + signature + credential_id
    Auth->>Auth: Verify signature with stored public key
    Auth-->>Device: Ed25519 session_id + access token + refresh token
Frontend -> backend -> /jwks verification
sequenceDiagram
    autonumber
    actor User
    participant Frontend
    participant Auth as Auth Mini Server
    participant Backend

    User->>Frontend: Complete sign-in
    Frontend->>Auth: Login / verify request
    Auth-->>Frontend: session_id + access token + refresh token
    Frontend->>Backend: App API request (Bearer access token)
    Backend->>Auth: GET /jwks
    Auth-->>Backend: Public signing keys
    Backend->>Backend: Verify JWT signature and claims
    Backend-->>Frontend: Protected resource

Quick Start

Pre-requisites:

  • Optional SMTP service credentials for email OTP. Admin Ed25519 bootstrap does not require SMTP. Most email providers have SMTP options, or you can use transactional email services like SendGrid, Mailgun, etc.

Install the release binary for your platform, verify its checksum, and put auth-mini on PATH:

curl -LO https://github.com/zccz14/auth-mini/releases/download/latest/auth-mini-linux-x86_64.tar.gz
curl -LO https://github.com/zccz14/auth-mini/releases/download/latest/auth-mini-linux-x86_64.tar.gz.sha256
shasum -a 256 -c auth-mini-linux-x86_64.tar.gz.sha256
tar -xzf auth-mini-linux-x86_64.tar.gz
chmod +x auth-mini
sudo mv auth-mini /usr/local/bin/auth-mini
auth-mini

Use the matching archive for your platform from the GitHub Release assets. The npm package no longer provides a CLI; it only ships SDK exports. The released Rust binary is the auth-mini server runtime.

Start the server. With no arguments, auth-mini listens on 127.0.0.1:7777 and stores SQLite data at ~/.auth-mini/default.sqlite3:

auth-mini

For deployment, the CLI only accepts the bind host, bind port, and database path:

auth-mini --host 127.0.0.1 --port 7777 --db ./auth-mini.sqlite

Initialize the administrator Ed25519 credential from the demo setup screen, or call the loopback-only admin setup API from the machine running auth-mini:

curl -X PUT http://127.0.0.1:7777/admin/setup \
  -H 'content-type: application/json' \
  -d '{"admin_ed25519":{"name":"ops laptop","public_key":"<base64url-ed25519-public-key>"}}'

After admin sign-in, configure the externally visible issuer, passkey RP ID, and optional SMTP settings from the admin configuration page or /admin/config. The issuer is stored at app_meta.issuer, and passkey registration/login use the single app_meta.rp_id; the WebAuthn origin is the Auth Mini server origin derived from the issuer. SMTP is not required for bootstrap, the SMTP password is never returned, and admin_ed25519 can create an admin user without an email address for later Ed25519 login. An Ed25519 session may register that user's first PassKey; after one is stored, additional PassKey registration requires an email OTP or WebAuthn session. HTTP CORS is served with Access-Control-Allow-Origin: *, so downstream apps need to manage that exposure carefully.

When the Rust binary DB path is omitted, it uses ~/.auth-mini/default.sqlite3. Server startup creates the SQLite file, parent directory, app_meta, JWKS keys, and schema automatically when missing. The Rust binary prints the SQLite database path it uses to stderr. The Rust binary embeds the database schema and openapi.yaml; runtime initialization uses the embedded schema. The Rust runtime has no --openapi parameter, and /openapi.yaml plus /openapi.json do not depend on the current working directory.

Then deploy it with your preferred hosting method.

Minimal browser SDK usage:

import { createBrowserSdk } from 'auth-mini/sdk/browser';

const sdk = createBrowserSdk('https://auth.your-domain.com');

sdk.session.onChange((state) => {
  console.log('auth status:', state.status);
});

Minimal device SDK usage:

import { createDeviceSdk } from 'auth-mini/sdk/device';

const sdk = createDeviceSdk({
  serverBaseUrl: 'https://auth.your-domain.com',
  privateKeySeed: '7rANewlCLceTsUo9feN0DLjnu-ayYsdhkVWvHT4FelM',
});

await sdk.ready;

Minimal backend JWT verification (jose example):

import { createRemoteJWKSet, jwtVerify } from 'jose';

const issuer = 'https://auth.your-domain.com';
const audience = 'app.your-domain.com';
const JWKS = createRemoteJWKSet(new URL(`/jwks`, issuer));

async function verifyAccessToken(token) {
  try {
    const { payload } = await jwtVerify(token, JWKS, {
      issuer,
      audience,
    });
    console.log('Token is valid. Payload:', payload);
  } catch (err) {
    console.error('Invalid token:', err);
  }
}

From there, typical integration looks like this:

  • start auth-mini with --host, --port, and --db as needed
  • initialize the admin Ed25519 credential, then configure issuer, passkey RP ID, and optional SMTP from the admin configuration page or /admin/config
  • sign in via email OTP and optionally register a passkey
  • send the access token to your backend and verify it with /jwks

Docs and next steps

docs/ is the canonical static reference source. ui-web/ is the current interactive demo source and Pages publish target, while the deployed live demo remains the easiest way to try the browser flows end-to-end.

Integration guides

Choose the guide that matches the part of your app integrating with Auth Mini:

Reference

The integration guides describe app-facing flows and SDK usage; the reference pages document the HTTP contract and server operations.

Philosophy

Why not a full auth platform?

If your project only needs authentication, a larger backend platform can be unnecessary overhead. auth-mini focuses on the auth slice so you can keep users, sessions, SMTP config, and signing keys understandable.

Why email OTP + passkeys?

Email is familiar and useful for recovery and communication. Passkeys then provide phishing-resistant, username-less sign-in with discoverable credentials instead of another password system.

Why SQLite?

Auth data is usually small, and operational simplicity matters. SQLite is easy to run, back up, inspect, and move without introducing another server just because auth sounds important.

Why access + refresh tokens?

Access tokens stay short-lived and verifiable by APIs through /jwks; refresh tokens stay revocable and database-backed. That keeps backend verification simple without pretending leaked JWTs are easy to revoke.

Development

Run npm run format, npm run lint, npm run typecheck, and npm test.

Release version rule

Git tag vX.Y.Z is the single source of truth for a release version. Before pushing a release tag, manually set package.json, rust-backend/Cargo.toml, and the auth-mini package entry in rust-backend/Cargo.lock to X.Y.Z, then run npm run check:release-version -- vX.Y.Z.

The release workflows fail before building binaries when the tag or any manifest version does not match. The check never bumps versions or creates release tags.

License

MIT License