Skip to content

Authentication & Authorization

Overview

CaseSolo uses JWT-based authentication with HTTP-only refresh token rotation.

Auth Flow

1. POST /api/auth/login    → { accessToken, user } + Set-Cookie: refreshToken
2. GET  /api/auth/me        → { user } (using accessToken in Authorization header)
3. POST /api/auth/refresh   → { accessToken } (using refreshToken cookie)
4. POST /api/auth/logout    → Clear refreshToken cookie

Access Tokens

Refresh Tokens

Route Protection

Server-side (API routes)

import { getCurrentUser } from '@/lib/auth/get-user'

export async function GET(req: Request) {
  const user = await getCurrentUser(req)
  if (!user) return Response.json({ error: 'Unauthorized' }, { status: 401 })
  // user.firmId, user.role available
}

Middleware

src/proxy.ts intercepts all /api/ and dashboard routes, verifying the JWT and injecting user context.

RBAC (Role-Based Access Control)

Roles (ordered by privilege)

| Role | Level | |------|-------| | SUPER_ADMIN | Platform-wide admin | | ADMIN | Firm admin — settings, billing, members | | ATTORNEY | Full case access, AI tools | | PARALEGAL | Case access, limited settings | | INTAKE_SPECIALIST | Leads, intake, case creation | | CLIENT | Portal access only | | READONLY | View-only dashboard access |

Permission Check

import { requireRole } from '@/lib/auth/rbac'

// In route handler:
requireRole(user, ['ADMIN', 'ATTORNEY']) // throws 403 if unauthorized

MFA, Passkeys, and Security Policy

Main-app MFA is implemented through /api/auth/mfa/setup, /api/auth/mfa/verify, and login-time MFA action tokens.

Firm-level security policy is exposed at /api/settings/security for ADMIN and SUPER_ADMIN users:

Store MFA encryption keys in MFA_SECRET_ENCRYPTION_KEY. If unset, the app falls back to JWT_SECRET for local/dev compatibility.

Client Portal Auth

The client portal uses a separate JWT flow:

Security Headers

Applied via next.config.ts:

Environment Variables

JWT_SECRET=           # HS256 signing key (min 32 chars)
JWT_REFRESH_SECRET=   # Refresh token signing key
MFA_SECRET_ENCRYPTION_KEY= # 32+ char secret for encrypted TOTP and SSO secret envelopes

Source: docs/dev/authentication.md