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_sessionsecretEnvKey:AUTH_SECRETsessionEnabled: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_KEYEMAIL_FROMGITHUB_CLIENT_IDGITHUB_CLIENT_SECRETGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETTURNSTILE_SECRETTURNSTILE_SITE_KEYORIGIN
Set these via Cloudflare secrets (wrangler secret put) or .dev.vars for local development.
What to read next
- Credentials and Sessions
- Magic Links
- Auth Context
- OAuth and RBAC
- Guards, CSRF, Rate Limits, and Turnstile
- Organizations and Schema
send_emailWorker binding (when using built-in magic-link delivery on Cloudflare Workers)