@pureq/auth
v1.1.0
Published
Zero-trust identity and authentication for pureq
Downloads
1,158
Maintainers
Readme
@pureq/auth
@pureq/auth is the authentication and session layer for the pureq ecosystem.
It is designed to give teams both:
- a short, practical onboarding path for shipping auth quickly
- explicit policy control for security, runtime behavior, and operations
Design Goals
- framework-neutral core that works across browser, SSR/BFF, Node, and edge
- explicit security and lifecycle contracts instead of hidden auth behavior
- production-aware adapter and provider ergonomics
- migration tooling that turns cutover risk into measurable checks
Comparison with Better Auth and Auth.js (NextAuth)
All three target modern TypeScript auth, but they optimize for different adoption and operations profiles.
| Concern | Better Auth (general tendency) | Auth.js / NextAuth (general tendency) | @pureq/auth |
| --- | --- | --- | --- |
| Primary orientation | framework/app integration speed | Next.js-centric ecosystem with broad adoption history | policy-explicit, framework-neutral core |
| Default developer flow | batteries-included framework DX | strong Next.js onboarding and established provider patterns | AuthKit/Starter fast path plus explicit lower-level control |
| Runtime model | framework-focused server flows | primarily Next.js server/client integration surface | browser, SSR/BFF, Node, and edge with shared primitives |
| Security visibility | secure defaults in framework context | battle-tested defaults with framework conventions | explicit mode-based defaults and policy override diagnostics |
| Adapter production gate | adapter usage depends on app checks | adapter ecosystem maturity is strong, readiness checks are app-defined | built-in readiness assessment (probe + assess) |
| Migration support | docs-driven migration | migration mostly docs/conventions and ecosystem tooling | diagnostics APIs and cutover/rollback checklist generation |
Use Better Auth when tight framework-native velocity is the top priority.
Use Auth.js/NextAuth when Next.js ecosystem fit and long adoption history are the primary decision factors.
Use @pureq/auth when you need one auth core with explicit policy boundaries, deployment-readiness gates, and migration telemetry across mixed runtimes.
What Is Included
Core construction APIs
- createAuth
- createAuthKit
- createAuthStarter
Route and framework integration
- createAuthRouteHandlerRecipe
- createAuthServerActionRecipe
- createAuthFrameworkContext
- createAuthRequestAdapter
- createNextAuthKitPack
- createExpressAuthKitPack
- createFastifyAuthKitPack
- createReactAuthKitBootstrapPack
Session and state lifecycle
- createAuthSessionManager
- createAuthSessionStore
- createReactAuthHooks
- createVueAuthSessionComposable
- createBufferedSessionEventExporter
- composeSessionEventAudits
- createConsoleSessionEventAudit
Providers and OIDC
- credentialsProvider
- emailProvider
- createTopProviderPreset
- listTopProviderPresets
- createOIDCFlow
- createOIDCFlowFromProvider
- oidcProviders
- validateProviderCallbackContract
- normalizeProviderError
- PROVIDER_ERROR_NORMALIZATION_TABLE
Adapters and SQL
- createInMemoryAdapter
- createPostgresAdapter
- createMySqlAdapter
- createSqlAdapter
- createPostgresExecutor
- createMySqlExecutor
- getSqlSchemaStatements
- probeAdapterCapabilities
- assessAdapterReadiness
Security controls
- createAuthCsrfProtection
- withCsrfProtection
- createAuthRevocationRegistry
- withRevocationGuard
- authEncryptedStore
- createAuthEncryption
- verifyJwt
Migration and diagnostics
- normalizeLegacyAuthTokens
- migrateLegacyTokensToStore
- hydrateSessionManagerFromLegacy
- analyzeAuthMigration
- formatMigrationParityReport
- generateMigrationChecklists
Installation
pnpm add @pureq/authQuick Start (Recommended)
For the shortest implementation path, start from createAuthStarter.
import { createAuthStarter, createInMemoryAdapter, credentialsProvider } from "@pureq/auth";
import { verify } from "argon2";
async function verifyPassword(email: string, password: string): Promise<{ id: string; email: string } | null> {
const user = await db.user.findUnique({ where: { email } });
if (!user) {
return null;
}
const ok = await verify(user.passwordHash, password);
return ok ? { id: user.id, email: user.email } : null;
}
const starter = await createAuthStarter({
security: { mode: "ssr-bff" },
adapter: createInMemoryAdapter(),
providers: [
credentialsProvider({
authorize: async (credentials) => {
return verifyPassword(credentials.username, credentials.password);
},
}),
],
});
export const handlers = starter.kit.handlers;AuthKit-First Setup
If you want explicit assembly while keeping strong defaults, use createAuthKit.
import { createAuthKit, createInMemoryAdapter } from "@pureq/auth";
const kit = createAuthKit({
security: { mode: "ssr-bff" },
adapter: createInMemoryAdapter(),
});
export const { handleSignIn, handleCallback, handleSession, handleSignOut } = kit.handlers;Providers
@pureq/auth provides two ways to integrate OAuth/OIDC providers, balancing ease of use with strict type safety and zero-trust security.
1. Explicit Provider Classes (Recommended)
Import dedicated provider classes for perfect IntelliSense and verified profile mapping.
import { PureqAuth } from "@pureq/auth";
import { GithubProvider, GoogleProvider } from "@pureq/auth/providers";
import { t } from "@pureq/db";
const UserSchema = t.record({
id: t.string(),
email: t.string(),
name: t.string(),
avatarUrl: t.string().optional(),
});
export const auth = new PureqAuth({
providers: [
new GithubProvider({
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
// Zero-trust profile mapping:
// The 'profile' argument is verified via OIDC backchannel exchange.
mapProfile: (profile) => ({
id: profile.id.toString(),
email: profile.email,
name: profile.name ?? profile.login,
avatarUrl: profile.avatar_url,
}),
}),
],
profileSchema: UserSchema,
});2. Built-in Presets (Fast Onboarding)
Use presets to quickly generate OIDC configurations with sensible default mappings.
import { createTopProviderPreset } from "@pureq/auth";
const google = createTopProviderPreset("google");
const line = createTopProviderPreset("line");Security & Zero-Trust Identity
Pureq Auth implements a Zero-Trust Identity model for callbacks:
- Backchannel Exchange: Unlike insecure implementations, Pureq never trusts identity claims passed directly in URL parameters (like
emailoruser_id). It always exchanges thecodefor tokens via a secure server-to-server call. - Strict Validation: If a provider fails to return a verified email or unique identifier, the authentication flow is aborted rather than falling back to insecure defaults.
- Randomized Sessions: Session tokens are 32-byte cryptographically secure random IDs, preventing session hijacking through ID guessing.
- Schema Enforcement: Use
profileSchemato ensure that mapped profiles conform to your application's requirements before they ever reach your database adapter.
Supported Standard Providers
| Category | Providers | | --- | --- | | Social | Google, Apple, Facebook, X (Twitter), GitHub, Discord, Slack, LINE, Twitch | | Enterprise | Microsoft (Entra ID), Okta, Auth0, LinkedIn | | Development | GitLab, Amazon, Generic OIDC |
SQL Adapters and Readiness
import {
createPostgresAdapter,
getSqlSchemaStatements,
assessAdapterReadiness,
} from "@pureq/auth";
const adapter = createPostgresAdapter(pgPool);
const report = assessAdapterReadiness(adapter, {
deployment: "production",
requireEmailProviderSupport: true,
});
if (report.status !== "ready") {
throw new Error(`adapter not ready: ${report.status}`);
}
for (const sql of getSqlSchemaStatements("postgres")) {
await pgPool.query(sql);
}Versioned SQL templates are included in:
Security Model
Automatic behavior
- OIDC callback replay protection with TTL cache
- JWT verification hardening (no alg:none acceptance)
- secure cookie defaults in cookie-backed flows
Opt-in behavior
- CSRF middleware for browser-mutating endpoints
- revocation guard for jti/sid/sub invalidation
- encrypted token storage
- broadcast sync for multi-tab state propagation
Encryption key management
createAuthEncryption(secret)requires at least 256-bit key material (32+ bytes).- Keep secrets in environment variables or managed secret stores (Vercel / AWS SSM / Doppler).
- Plan periodic key rotation in operations; current encrypted payload compatibility is single-key.
- Default PBKDF2 iterations is
100_000; for password-derived secrets, consider600_000+.
Runtime-mode defaults
Security defaults are mode-aware:
- browser-spa
- ssr-bff
- edge
Policy overrides are diagnosable through onPolicyOverride hooks.
Migration Workflow
Migration helpers are provided for:
- legacy token normalization
- store/session hydration
- parity report generation
- cutover and rollback checklist generation
Starter can run adapter preflight at process boot and fail early on blocked readiness.
Framework and Runtime Coverage
Core primitives are framework-neutral.
Thin packs and recipes are provided for:
- Next.js
- Express
- Fastify
- React bootstrap
- SSR/BFF bridge patterns
- edge-compatible context and response handoff
Documentation
- Documentation Index
- Package Overview
- AuthKit Quickstart
- Auth Starter
- Implementation Examples
- Framework Packs
- Framework Adapters
- Framework Hooks
- Security Controls
- Session Event Operations
- SSR Bridge
- SQL Adapters Quickstart
- Adapter Compatibility Matrix
- Adapter Harness
- Provider Priorities
- Provider Error Normalization
- Migration Guide
- Migration Playbook
- Templates and Presets
- Event Adapters
- Error Code Reference
Testing
pnpm --filter @pureq/auth test:unit
pnpm --filter @pureq/auth test:contract
pnpm --filter @pureq/auth test:integrationLicense
MIT © Shihiro
