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.
| Domain | Permissions |
|---|---|
| Account | account:update, account:delete |
| Billing | billing:view, billing:manage |
| Members | members:view, members:invite, members:remove, members:update_role |
| API Keys | api_keys:view, api_keys:create, api_keys:delete |
| AI | ai: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
Admins manage roles from /admin-dashboard/roles or via the admin API: GET/POST /api/admin/roles (list / create) and PATCH/DELETE /api/admin/roles/[roleId] (update / delete). Requests are admin-gated and CSRF-protected; is_system roles reject deletion.
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.