Skip to main content

Overview

Zelt provides a flexible authentication system that separates authentication (who is the user?) from authorization (what can they do?).

Authentication vs Authorization

ConceptQuestionZelt API
AuthenticationWho is the user?setUser(), currentUser()
AuthorizationWhat can they do?@Authorized(), currentRoles()

Authentication happens first (typically in middleware), then authorization checks run on protected routes.

Choose Your Strategy

Zelt supports multiple authentication strategies. Pick the one that fits your architecture:

StrategyBest ForPackage
JWTSPAs, Mobile apps, APIs@zeltjs/auth-jwt
SessionsServer-rendered apps, Traditional web apps@zeltjs/auth-session
CustomAPI keys, OAuth, or any other methodBuilt-in primitives

Decision Guide

Is your client a browser with server-side rendering?
├── Yes → Sessions (cookie-based, automatic CSRF handling)
└── No
    ├── SPA or Mobile app? → JWT (stateless, scalable)
    └── Machine-to-machine API? → Custom (API keys, mTLS)

Authentication Flow

Request

┌─────────────────────────────┐
│ Authentication Middleware   │
│ • Extract credentials       │
│ • Verify (JWT/Session/etc)  │
│ • setUser(user, roles)      │
└─────────────────────────────┘

┌─────────────────────────────┐
│ @Authorized() Check         │
│ • No user? → 401            │
│ • Missing role? → 403       │
│ • OK → Continue             │
└─────────────────────────────┘

Route Handler

Response

Quick Start

1. Install a package (or use built-in primitives)

# For JWT authentication
pnpm add @zeltjs/auth-jwt

# For session authentication
pnpm add @zeltjs/auth-session @zeltjs/kv

2. Register middleware

const app = createApp([http({
    controllers: [UserController],
    middlewares: [JwtMiddleware],
  })], { configs: [JwtConfig] });

3. Protect routes

@Controller('/dashboard')
class DashboardController {
  @Authorized()
  @Get('/')
  index() {
    const user = currentUser();
    return { message: `Hello, ${user?.name}` };
  }
}

Next Steps