← All projects

issuer-node

  • TypeScript 99.33%
  • Shell 0.48%
  • JavaScript 0.19%
git@gitlab.com:aice-lab/auth/issuer-node.git

Latest release

v0.2.1 ·

README

@aice-lab/auth-issuer

pipeline status coverage report

Server-side issuer for the aice-auth specification. Mounts as an Express router into your Node application and provides the /auth/* and /.well-known/* endpoint surface — accounts, handles, credentials, sessions, refresh-token rotation, JWKS, OIDC discovery.

@aice-lab/auth (sibling package) is the client-side verifier. @aice-lab/auth-issuer is the server-side issuer. You use both: the issuer hosts the endpoints, the verifier validates incoming bearer tokens on your own protected routes.

This package is distributed as @aice-lab/auth-issuer via the aice-lab GitLab npm registry (anonymous public read).

Install

Add the @aice-lab scope to your project’s .npmrc:

@aice-lab:registry=https://gitlab.com/api/v4/groups/aice-lab/-/packages/npm/

If you use pnpm v10+, also:

lockfile-include-tarball-url=true

Then install:

npm install @aice-lab/auth-issuer
# or
pnpm add @aice-lab/auth-issuer

Requires Node.js ≥ 20. SQLite is the default (zero-dep, single-file); Postgres ≥ 14 remains supported. Express ≥ 4.18 is a peer dependency.

Quickstart (SQLite)

import express from 'express';
import {
  createAuthIssuerRouter,
  createKyselyFromSqlite,
  migrate,
  handleHmacKeyFromHex,
} from '@aice-lab/auth-issuer';

const db = createKyselyFromSqlite('./auth.db');
await migrate(db);

// Note: createAuthIssuerRouter installs its own JSON body parser internally —
// do NOT add `app.use(express.json())` before it (double-parsing breaks POSTs).
const app = express();
app.use(createAuthIssuerRouter({
  db,
  otpIssuer,                                 // see @aice-lab/otp-issuer
  handleHmacKey: handleHmacKeyFromHex(process.env.HANDLE_HMAC_KEY_HEX!),
  signingKeys: [activeKey],                  // ES256 JWKs
  issuer: 'http://localhost:4000',
  audience: 'my-app',
  verifyUrlBase: 'http://localhost:4000/auth/verify',
}));
app.listen(4000);

Quickstart (Postgres)

Same shape — swap the factory:

import { Pool } from 'pg';
import { createKyselyFromPgPool, migrate } from '@aice-lab/auth-issuer';

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const db = createKyselyFromPgPool(pool);
await migrate(db);

// pass `db` into createAuthIssuerRouter(...) exactly as above.

What ships in v0.1

EndpointPurpose
POST /auth/registerCreate account with handle + initial credential
POST /auth/loginHandle+credential login → access + refresh tokens
POST /auth/refreshAtomic refresh-token rotation (replay revokes chain)
POST /auth/logoutRevoke caller’s session + refresh chain
POST /auth/handles/emailAdd unverified email handle, dispatch magic-link OTP
POST /auth/handles/email/:id/verifyConsume magic-link OTP, mark handle verified
POST /auth/recover/startEnumeration-safe recovery initiation
POST /auth/recover/verify-handleConsume recovery OTP → limited-scope (auth:recover) access token
POST /auth/credentials/passwordRotate password (requires auth:recover scope or acr=aal2)
GET /auth/sessionsList caller’s active sessions (current flagged)
DELETE /auth/sessions/:idRevoke a peer session of the caller
GET /.well-known/openid-configurationOIDC discovery
GET /.well-known/jwks.jsonPublic signing keys

Schema is consumed from aice-lab/auth/spec migrations 0001–0011 via the bundled migrate(db) helper. Tables use the auth_* prefix (e.g. auth_accounts, auth_sessions) so the same migration set works on Postgres and SQLite.

What’s deferred

OAuth2 /oauth2/* endpoints, passkey (WebAuthn), TOTP, recovery-codes, social handles, phone-handle verification, step-up via OTP, revoke-all-others, handle/{id}/primary — these are out of v0.1 scope (will land iteratively as downstream products need them).

License

Source: FSL-1.1-Apache-2.0 (see LICENSE and LICENSE.FAQ.md).

Documentation

Full architecture: ARCHITECTURE.md. Conformance harness: conformance/README.md.

Contributing

See CONTRIBUTING.md. TDD is mandatory; every code change ships with a corresponding test commit. DCO sign-off on every commit (git commit -s).

Reporting security issues

See SECURITY.md. Do not open public issues for vulnerabilities.

This is a snapshot generated from GitLab. For the live README, see the project page.