Getting Started | Kyzen | Primitives Docs

Getting Started

Install kyzen and wire it into your Koze middleware

What this is

kyzen is the Koze quickstart auth library. It gets you to "users can sign in" fast - credentials, magic links, sessions, role-based permissions, rate limiting, CSRF/origin checks, OAuth, Turnstile bot protection - driven by a single config object that you pass to a middleware factory.

It's a starter, not a standard. The framework has no built-in auth; kyzen plugs in via ordinary middleware, the same shape any other auth library would use. If you outgrow it (federated identity, complex authorization graphs, custom session backends), swap it out - nothing else in your app cares.

Install

npm install @kuratchi/kyzen @kuratchi/kunii

kyzen depends on ORM-backed tables for users, sessions, magic-link tokens, OAuth accounts, activity logs, and related auth state.

Minimal setup

Auth is wired through middleware. For Koze, the primary adapter is kyzen/koze. Keep the config in its own module so it's easy to find and easy to test, then import it into src/middleware.ts.

// src/server/auth-config.ts
import { kyzenAuthConfig } from '@kuratchi/kyzen/adapter';

export const authConfig = kyzenAuthConfig({
  cookieName: 'kuratchi_session',
  sessionEnabled: true,
  credentials: { binding: 'DB' },
  csrf: {
    paths: ['/auth/*'],
  },
  guards: {
    paths: ['/admin/*'],
    redirectTo: '/auth/login',
  },
});
// src/middleware.ts
import { defineMiddleware } from '@kuratchi/koze';
import { initKyzenAuth } from '@kuratchi/kyzen/koze';
import { authConfig } from '$server/auth-config';

const auth = initKyzenAuth(authConfig);

export default defineMiddleware({
  auth: auth.middleware(),
});

That is the primary integration point. kyzen/middleware remains available as the lower-level compatibility path, but kyzen/koze is the first-class adapter for framework apps.

Adapter defaults

kyzenAuthConfig({...}) is an optional helper that fills in sensible defaults. You can pass a plain object to auth.middleware() or kyzenAuthMiddleware() directly; the adapter just adds:

  • cookieName: kuratchi_session
  • secretEnvKey: AUTH_SECRET
  • sessionEnabled: true

Common imports

Once the middleware is wired, the auth helpers become available in any route, action, or $server/* module:

import {
  signUp,
  signIn,
  signOut,
  getCurrentUser,
  getAuth,
  requestMagicLink,
  consumeMagicLink,
  requestPasswordReset,
  resetPassword,
  verifyEmail,
  resendEmailVerification,
  inviteMember,
  acceptInvite,
  logActivity,
  hasRole,
  hasPermission,
  startOAuth,
  handleOAuthCallback,
  requireAuthGuard,
  verifyTurnstile,
} from '@kuratchi/kyzen';

All of these read from request-scoped locals populated by auth middleware. Call them from route handlers, actions, RPC functions - the auth context is available wherever the framework runs request code.

Single-tenant vs multi-tenant

kyzen supports two modes:

Mode When Storage
Single-tenant One shared user pool. No organizations. All auth tables on the admin D1 binding.
Org-mode Per-organization isolation. Each org gets its own SQLite-backed Durable Object. Admin D1 stores organizations + organizationUsers + verification tokens; users + sessions live inside each org's DO.

Org-mode is the more interesting case (and the one the framework's reference app, apps/web, runs in). Switch it on with the organizations config block - see Organizations and Schema.

Required env

At minimum, auth flows expect:

  • AUTH_SECRET

Feature-specific flows can also require:

  • RESEND_API_KEY
  • EMAIL_FROM
  • GITHUB_CLIENT_ID
  • GITHUB_CLIENT_SECRET
  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • TURNSTILE_SECRET
  • TURNSTILE_SITE_KEY
  • ORIGIN

Set these via Cloudflare secrets (wrangler secret put) or .dev.vars for local development.