TUTORIAL 03 · INTERMEDIATE

Authentication with Email, Password and JWT

Add persisted users, email/password registration, password hashing and JWT sessions to ServiceDesk.

RAIQL 1.025 minProject: ServiceDesk
By the end of this tutorial
  • Declare a generated User entity
  • Generate registration and login
  • Use EMAIL_PASSWORD + JWT
  • Keep the JWT signing secret outside source control

Declare identity explicitly

Authentication is generated only when it is declared. CREATE USER ENTITY User creates the identity model; ADD AUTHENTICATION selects the supported authentication mechanisms.

app.raiql
CREATE APPLICATION "RAIQL ServiceDesk";
TYPE WEB;

USE STACK
  FRONTEND NEXTJS,
  BACKEND NEXTJS,
  DATABASE POSTGRESQL;

CREATE USER ENTITY User;

CREATE ENTITY Ticket (
  id UUID PRIMARY,
  title STRING REQUIRED,
  description STRING,
  status STRING REQUIRED,
  priority STRING REQUIRED,
  ownerId UUID REQUIRED
);

CREATE CRUD Ticket;
CREATE API Ticket;

ADD AUTHENTICATION EMAIL_PASSWORD, JWT;
ADD ROLE ADMIN, USER;
DEFAULT ROLE USER;

RELATE Ticket.ownerId TO User.id;
OWN Ticket BY ownerId;

ALLOW ADMIN CREATE Ticket, READ Ticket, UPDATE Ticket, DELETE Ticket;
ALLOW USER CREATE OWN Ticket, READ OWN Ticket, UPDATE OWN Ticket;

ENVIRONMENT development, staging, production;
SECRET DATABASE_URL;
SECRET RAIQL_JWT_SECRET;

BUILD;
DEPLOY DOCKER;

Why ownerId is present

The Ticket now references User because later authorization decisions need a stable ownership relationship. RELATE validates that relationship at compile time.

  • User.id is the identity key
  • Ticket.ownerId references User.id
  • OWN Ticket BY ownerId establishes record ownership

Prepare development secrets

terminal
raiql env list
raiql env init development
raiql env check development

Run and test login

Start the app, open /register, create an account, then use /login. Generated password handling uses salted scrypt hashing and issues a JWT after successful authentication.

terminal
raiql dev --env development
# open http://localhost:3000/register
# then http://localhost:3000/login

Security boundary

RAIQL ruleRAIQL assigns DEFAULT ROLE USER during public registration. A client cannot promote itself to ADMIN by posting a role value.