DeployStack Docs

Role Management System

This guide explains how to manage roles and permissions in the DeployStack backend for developers.

Overview

DeployStack uses a centralized role-based access control (RBAC) system with automatic synchronization between code definitions and database storage.

Role Definitions

All roles and permissions are defined in a single file:

services/backend/src/permissions/index.ts

This is the single source of truth for all role definitions. To see current roles and their permissions, check this file.

Role Types

The system supports two types of roles:

  • Global Roles: System-wide roles (global_admin, global_user)
  • Team Roles: Team-specific roles (team_admin, team_user)

Team roles are assigned within team contexts and work alongside global roles to provide fine-grained access control for team-based resources.

Database Storage

Roles are stored in the roles table with the following structure:

  • id - Role identifier (e.g., 'global_admin')
  • name - Display name (e.g., 'Global Administrator')
  • description - Role description
  • permissions - JSON array of permission strings
  • is_system_role - Boolean flag for core system roles
  • created_at / updated_at - Timestamps

User role assignments are stored in the authUser.role_id column.

Automatic Synchronization

The system automatically syncs role permissions from code to database on server startup. The RoleSyncService compares the definitions in permissions/index.ts with the database and updates any differences. This ensures the database always matches your code definitions without manual intervention.

Adding New Roles

1. Define the Role

Add your new role to services/backend/src/permissions/index.ts:

export const ROLE_DEFINITIONS = {
  // ... existing roles
  content_moderator: [
    'users.view',
    'content.moderate',
    'reports.view',
  ],
} as const;

2. Create Database Migration (Optional)

If you want the role available immediately in existing databases, create a migration:

-- Add new role to existing databases
INSERT OR IGNORE INTO `roles` (`id`, `name`, `description`, `permissions`, `is_system_role`, `created_at`, `updated_at`) VALUES 
('content_moderator', 'Content Moderator', 'Manages user content', '[]', 1, strftime('%s', 'now') * 1000, strftime('%s', 'now') * 1000);

3. Restart Server

The RoleSyncService will automatically populate the role's permissions from your code definition on the next server startup.

Permission System

Available Permissions

All permissions are auto-generated from role definitions. The AVAILABLE_PERMISSIONS array in permissions/index.ts contains all unique permissions across all roles, sorted alphabetically.

Permission Checking

Use the middleware functions for route protection:

import { requirePermission } from '../middleware/roleMiddleware';

// Require specific permission
fastify.get('/admin-endpoint', {
  preValidation: requirePermission('system.admin')
}, handler);

For team-based resources, use team-aware permissions:

import { requireTeamPermission } from '../middleware/roleMiddleware';

// Team-specific permission checking
fastify.post('/teams/:teamId/resources', {
  preValidation: requireTeamPermission('resources.create')
}, handler);

See API Security Best Practices for detailed information about team-aware permissions and security patterns.

Programmatic Checks

import { checkUserPermission } from '../middleware/roleMiddleware';

const hasPermission = await checkUserPermission(userId, 'users.edit');

API Endpoints

Role Management

  • GET /api/roles - List all roles
  • POST /api/roles - Create new role
  • PUT /api/roles/:id - Update role
  • DELETE /api/roles/:id - Delete role

User Role Assignment

  • PUT /api/users/:id/role - Assign role to user
  • GET /api/users/me - Get current user with role info

Best Practices

  • Single Source: Always define roles in permissions/index.ts
  • Descriptive Names: Use clear permission names with dot notation (users.edit, content.moderate)
  • Minimal Permissions: Give roles only the permissions they need
  • System Roles: Mark core roles as is_system_role: true to prevent deletion
  • Testing: Test permission changes in development before deploying

Security Notes

  • System roles cannot be modified or deleted via API
  • Users cannot change their own roles
  • The last global administrator cannot be deleted
  • All permission checks happen server-side