Site

Roles control who can do what inside an account. The boilerplate ships three system roles (owner, admin, member) plus a permission matrix and supports custom roles via the admin dashboard.

Roles & Permissions

The boilerplate includes a dynamic, database-driven roles system. Roles are managed from the admin dashboard and stored in the roles table.

System Roles

Three system roles are protected and cannot be deleted:

Role Slug Description Deletable
Owner owner Full control over the workspace. Can delete the organization. No
Admin admin Can manage members and settings, but cannot delete the workspace. No
Member member Standard access. Can use features but cannot manage team. No

Permission Matrix

Permission Owner Admin Member
Use AI / Chat✓✓✓
View members✓✓✓
Invite members✓✓✗
Remove members✓✓✗
View billing✓✓✗
Manage billing✓✗✗
Create API keys✓✓✗
Change member roles✓✗✗
Edit workspace settings✓✓✗
Delete workspace✓✗✗

Available Permissions

The 12 built-in permissions, grouped by domain. Custom roles combine any subset; system roles (owner > admin > member) are seeded with sensible defaults.

DomainPermissions
Accountaccount:update, account:delete
Billingbilling:view, billing:manage
Membersmembers:view, members:invite, members:remove, members:update_role
API Keysapi_keys:view, api_keys:create, api_keys:delete
AIai:use

Checking Permissions

Use checkPermission() from lib/permissions/check.ts — it resolves the current user, their membership on the account, and the role's JSONB permission set:

import { checkPermission } from '@/lib/permissions/check'

const canInvite = await checkPermission(accountId, 'members:invite')
if (!canInvite) return Response.json({ error: 'Forbidden' }, { status: 403 })

Creating Custom Roles

Platform administrators manage roles from /admin-dashboard/roles or via the admin API: GET/POST /api/admin/roles (list / create) and GET/PATCH/DELETE /api/admin/roles/[roleId] (read / update / delete). Mutations require CSRF protection, the strict rate limit and the configured adminEscalation reauthentication policy. Each mutation and its audit commit together. The owner role cannot be modified; system roles and roles referenced by members or invitations cannot be deleted.

Permission changes are read fresh on subsequent requests. An unavailable role catalogue is reported as an error rather than an empty catalogue or a zero usage count. The catalogue limit is configured in config/roles.ts and is enforced by the installed database contract; exceeding it fails explicitly. Direct table writes to roles are unavailable: use the bounded administrative Prisma capability. Database and authentication provider certifications remain separate from local implementation tests.

Role Database Schema

Roles are stored in the roles table with fields for slug (unique identifier), name, permissions (JSONB array of permission strings), color, icon, and an is_system flag that protects built-in roles (owner, admin, member) from deletion. Custom roles can be created with any combination of permissions from the available permission set.