Skip to content

Authentication Overview

Velox TS ships with two authentication strategies — JWT for stateless APIs and sessions for server-rendered apps — plus guards, policies, rate limiting, and password hashing. Choose one strategy or combine them depending on your deployment model.

  • Guards.guard(authenticated), .guard(hasRole('admin')) for ctx-only authentication checks.
  • Policies — Laravel-style declarative resource authorization.
  • Post-Middleware Checks.check() for ad-hoc authorization that needs input plus middleware-extended ctx (e.g. resource ownership).
  • Resource API — auto-project response fields by public / authenticated / admin access level.
  • Raw Responses — return redirects + cookies from OAuth callbacks while staying inside the procedure system.
FeatureJWTSessions
StorageClient (token)Server (store)
ScalabilityStatelessRequires shared store
RevocationDifficultEasy
Use caseAPIs, mobileWeb apps, SSR

Token-based, stateless authentication with access/refresh token pairs:

import { jwtManager, authPlugin, authenticated } from '@veloxts/auth';
// Configure JWT with access and refresh tokens
const jwt = jwtManager({
secret: process.env.JWT_SECRET!,
refreshSecret: process.env.JWT_REFRESH_SECRET!,
accessTokenExpiry: '15m',
refreshTokenExpiry: '7d',
});
await app.register(authPlugin, { jwt });
// Protect procedures with guards
getProfile: procedure()
.guard(authenticated)
.query(({ ctx }) => ctx.user),

Learn more about JWT

Cookie-based, server-side sessions with secure defaults:

import { sessionMiddleware, inMemorySessionStore } from '@veloxts/auth';
const session = sessionMiddleware({
secret: process.env.SESSION_SECRET!, // 32+ chars
store: inMemorySessionStore(), // Use Redis in production
cookie: {
secure: true,
httpOnly: true,
sameSite: 'lax',
},
userLoader: async (userId) => db.user.findUnique({ where: { id: userId } }),
});
// Protect procedures
getProfile: procedure()
.use(session.required())
.query(({ ctx }) => ctx.user),

Learn more about Sessions

Protect procedures with authorization checks:

import { authenticated, hasRole, hasPermission } from '@veloxts/auth';
// Must be logged in
.guard(authenticated)
// Must have specific role
.guard(hasRole('admin'))
// Must have permission
.guard(hasPermission('users:write'))
// Chain multiple guards
.guard(authenticated)
.guard(hasRole('editor'))

Guards narrow ctx.user type - after authenticated, ctx.user is guaranteed to exist.

Learn more about Guards

Integrate third-party authentication providers like Clerk, Auth0, or Better Auth:

import { createClerkAdapter } from '@veloxts/auth/adapters';
import { createAuthAdapterPlugin } from '@veloxts/auth';
const adapter = createClerkAdapter({
name: 'clerk',
clerk: createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY! }),
});
const authPlugin = createAuthAdapterPlugin({ adapter, config: adapter.config });
app.register(authPlugin);

Learn more about Auth Adapters

Quick start with authentication:

Terminal window
npx create-velox-app my-app --auth
npx create-velox-app my-app --rsc-auth