Guards, CSRF, Rate Limits, and Turnstile
Apply runtime auth controls before route handlers run
These subsystems live as nested options on kyzenAuthMiddleware({...}). They run inside the auth middleware's pre-route check phase before route handlers: rate-limit, CSRF/origin checks, Turnstile, then guards.
// src/middleware.ts
kyzenAuthMiddleware({
guards: { /* see Guards below */ },
csrf: { /* see CSRF below */ },
rateLimit: { /* see Rate limiting below */ },
turnstile: { /* see Turnstile below */ },
});
Guards
Guards are configured with:
pathsexcluderedirectTo
Example:
guards: {
paths: ['/admin/*', '/dashboard/*'],
exclude: ['/auth/login'],
redirectTo: '/auth/login',
}
Runtime helpers:
checkGuard()requireAuthGuard
Important behavior:
checkGuard() only checks for the presence of the session cookie. It does not fully validate the session record. Route code should still call getCurrentUser() or getAuth().getSession() before trusting the request as authenticated.
CSRF and origin checks
CSRF protection is opt-in because existing apps may use different credential route names. Configure it on routes that mutate auth state, such as sign-in and sign-up form actions:
csrf: {
paths: ['/auth/signin', '/auth/signup'],
trustedOrigins: ['https://app.example.com', 'https://*.tenant.example.com'],
}
Behavior:
- Cross-site top-level POST navigations without cookies are rejected using Fetch Metadata headers.
- Unsafe requests with cookies validate the
Originheader against the request origin plustrustedOrigins. - Wildcard trusted origins match tenant subdomains.
Runtime helpers:
checkCsrf()configureCsrf(config)
Rate limiting
Configure rate limits per route:
rateLimit: {
defaultWindowMs: 60000,
defaultMaxRequests: 10,
kvBinding: 'RATE_LIMIT',
routes: [
{
id: 'auth-signin',
path: '/auth/signin',
methods: ['POST'],
maxRequests: 5,
windowMs: 60000,
message: 'Too many sign-in attempts.',
},
],
}
Runtime helpers:
checkRateLimit()getRateLimitInfo(routeId)
The limiter uses cf-connecting-ip and can persist counts in KV when configured, with an in-memory fallback per isolate.
Turnstile
Configure Turnstile with:
secretEnvsiteKeyEnvskipInDevroutes
Example:
turnstile: {
secretEnv: 'TURNSTILE_SECRET',
siteKeyEnv: 'TURNSTILE_SITE_KEY',
routes: [
{
id: 'auth-signin',
path: '/auth/signin',
methods: ['POST'],
expectedAction: 'signin',
},
],
}
Runtime helpers:
checkTurnstile()verifyTurnstile(token, options)
The verifier reads tokens from common headers or form fields, then calls Cloudflare's Turnstile verification endpoint.