Security
Relevant source files
The following files were used as context for generating this wiki page:The security architecture for Kodus Runtime is centered around a comprehensive JSON Web Token (JWT) system that provides authentication, session management, and role-based access control (RBAC) for the API. It handles user registration, login, token generation, and automatic token validation for protected routes. The system is designed to secure critical endpoints while allowing public access for authentication-related operations.
The core security logic is encapsulated within the @kodus/auth package, which provides utilities for JWT management and middleware for route protection. The API application (@kodus/api) consumes these utilities to implement the authentication flows and protect its resources. User data and credential validation are managed by a dedicated UserService.
Sources: README.md:15-21, packages/auth/package.json:3, apps/api/src/services/userService.ts
Authentication Architecture
The authentication system is built on two primary components: the JwtService for token operations and the UserService for user management. API routes exposed by the Elysia server handle the user-facing interactions like registration and login.
Key Components
| Component | Description | Source File |
|---|---|---|
authRoutes | Elysia API routes for /auth/register, /auth/login, /auth/refresh, and /auth/me. | apps/api/src/routes/auth.ts |
jwtService | Singleton service for generating and verifying JWT access and refresh tokens. | packages/auth/src/jwt.ts |
userService | Singleton service for creating, finding, and validating users. Manages an in-memory user store. | apps/api/src/services/userService.ts |
authenticate | Middleware that verifies the Authorization header and attaches the user payload to the request. | packages/auth/src/middleware.ts |
User and Role Management
User identity is managed by the UserService, which currently uses an in-memory Map to store user data and credentials. A default admin user is initialized on startup.
Sources: apps/api/src/services/userService.ts:8-11, 28
User Data Model
The User object contains essential identity and status information.
| Field | Type | Description |
|---|---|---|
id | string | Unique user identifier. |
email | string | User's email address, used for login. |
name | string | User's full name. |
role | UserRole | The role assigned to the user (e.g., ADMIN, USER). |
isActive | boolean | Flag indicating if the user account is active. |
createdAt | Date | Timestamp of user creation. |
updatedAt | Date | Timestamp of the last update. |
Sources: packages/auth/src/types.ts:2-11, apps/api/src/services/userService.ts:13-22
The diagram below shows the structure of the User entity.
Sources: packages/auth/src/types.ts:2-11
User Roles
The system defines a set of roles to control access to different resources.
| Role | Value | Description |
|---|---|---|
ADMIN | "admin" | Full access to all resources. |
USER | "user" | Standard user access. |
SERVICE | "service" | For machine-to-machine communication. |
Sources: packages/auth/src/types.ts:13-17
Authentication Flows
User Registration
A new user can be created via the /register endpoint. The service validates the input, checks for existing users, hashes the password using bcrypt, and creates a new user with the default USER role. Upon success, it generates and returns a new set of JWTs.
Sources: apps/api/src/routes/auth.ts:9-58, apps/api/src/services/userService.ts:60-89
The following sequence diagram illustrates the registration process.
User Login
Users authenticate by sending their credentials to the /login endpoint. The UserService validates the email and password against the stored hash. If successful, a new set of JWTs is generated and returned. The flow also checks if the user account is active.
Sources: apps/api/src/routes/auth.ts:61-114, apps/api/src/services/userService.ts:94-106
The login flow is shown in the diagram below.
Token Refresh
Access tokens have a short lifespan. When an access token expires, the client can use a long-lived refresh token to obtain a new pair of tokens from the /refresh endpoint without requiring the user to log in again. The service verifies the refresh token, finds the associated user, and issues new tokens.
Sources: apps/api/src/routes/auth.ts:117-171, packages/auth/src/jwt.ts:47-56
JWT Service
The JwtService is responsible for all token-related operations. It uses the jsonwebtoken library.
Sources: packages/auth/src/jwt.ts
Token Generation
The generateTokens method creates both an access token and a refresh token. Both tokens contain the user's ID, role, and email in their payload.
| Token Type | Expiration | Purpose |
|---|---|---|
accessToken | 15 minutes | To authorize access to protected API resources. |
refreshToken | 7 days | To obtain a new access token when the current one expires. |
Sources: packages/auth/src/jwt.ts:16-17, 30-44
The JwtService class structure is simple, containing methods for token generation and verification.
API Endpoint Protection
Route protection is implemented via middleware that checks for a valid JWT in the Authorization header.
Sources: packages/auth/src/middleware.ts, README.md:27-38
Middleware Flow
The authenticate middleware is the foundation for route protection. It extracts the token, verifies it using jwtService.verifyAccessToken, finds the user via userService.findById, and attaches the user object to the request context if authentication is successful.
Protected and Public Routes
The application defines which routes require authentication.
| Route | Method | Protection | Description |
|---|---|---|---|
/api/auth/register | POST | Public | Registers a new user. |
/api/auth/login | POST | Public | Authenticates a user and returns tokens. |
/api/auth/refresh | POST | Public | Refreshes an access token. |
/api/auth/logout | POST | Public | Client-side logout hint. |
/api/auth/me | GET | Protected | Retrieves the current authenticated user's info. |
/api/events | POST | Protected | Requires authentication to post events. |
/api/events/* | GET | Protected | Requires authentication to get events. |
/api/workflows/* | POST | Protected | Requires authentication for all workflow actions. |
Sources: README.md:34-38, apps/api/src/routes/auth.ts:6-196, apps/api/src/routes/workflows.ts:7
Middleware helpers like requireUser and requireAdmin build upon authenticate to enforce role-based access. For example, workflow routes are protected for any authenticated user.
// File: apps/api/src/routes/workflows.ts:7
export const workflowRoutes = new Elysia({ prefix: '/workflows' })
.use(requireUser) // Require authentication for all workflow routes
Sources: apps/api/src/routes/workflows.ts:7-8, packages/auth/src/middleware.ts:42-49