PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
Backend
    Audit SystemAuditable Joins and Display Name ResolutionAuditService and Delta CalculatorAuth Router: Login, Token Refresh, and User Management APIAuthentication and AuthorizationAuthentication Middleware and Token NormalizationCore ArchitectureCustomers API RouterCustomers Data Access LayerCustomers ModuleDatabase ManagementDocker Infrastructure and Casdoor SetupDomain Entity SystemExport LibraryGetting StartedGitFlow, Versioning, and CI HooksGlossaryInfrastructure and DevOpsMigration Patch Registry and ApplicationOpenAPI DocumentationOrganizations ModuleOverviewProject StructureRBAC Middleware and Permission SystemRepository and Query DSLSchema Snapshot and Diff SystemServer Bootstrap and Middleware PipelineUtility Scripts ReferenceREADME
Frontend
Microservices
powered by Zudoku
Backend

RBAC Middleware and Permission System

RBAC Middleware and Permission System

Relevant source files

The following files were used as context for generating this wiki page:

  • AGENTS.md
  • README.md
  • db-meta/patches/00000000000000_init_database.sql
  • docs/gitflow.md
  • src/modules/auth/README.md
  • src/modules/auth/oidc-client.ts
  • src/modules/auth/permissions.ts
  • src/modules/auth/rbac.middleware.ts
  • src/modules/auth/role-mapping-repo.ts
  • src/modules/auth/role_mapping_entity.ts
  • src/modules/auth/user-profile-repo.ts

The Primebrick backend implements a robust Role-Based Access Control (RBAC) system designed for granular security, wildcard-based permission matching, and seamless integration with external Identity Providers (IDP) like Casdoor. The system follows a declare-first policy where every route must explicitly state its required permissions via a specialized middleware.

Permission Registry and Structure

The system uses a single source of truth for all available permissions defined in the Permission enum. Permissions follow a hierarchical dot-notation pattern: module.action.granularity src/modules/auth/permissions.ts:88-89.

Permission Format Examples

  • customers.read.all: List all customers AGENTS.md:91.
  • customers.read.audit: Access customer audit trails AGENTS.md:93.
  • customers.delete.bulk: Perform bulk deletion operations AGENTS.md:99.
  • *: A global wildcard matching all permissions (effectively a super-user) AGENTS.md:110.

Permission Sentinels

Two pseudo-permissions act as sentinels and are handled directly by the middleware logic rather than role expansion src/modules/auth/permissions.ts:22-23:

  • Permission.PUBLIC (_public): Endpoint is reachable without a JWT. In GATEWAY mode, the gateway secret is still verified src/modules/auth/permissions.ts:37.
  • Permission.AUTHENTICATED_USER (_authenticated_user): Any caller with a valid token passes, regardless of specific roles src/modules/auth/permissions.ts:39.

Sources: src/modules/auth/permissions.ts:34-87, AGENTS.md:88-104

Role Mappings and Expansion

Role-to-permission mappings are stored in the role_mappings table src/modules/auth/role_mapping_entity.ts:16. This table decouples IDP roles (e.g., Casdoor roles) from internal system permissions.

Role Mapping Table Structure

ColumnTypeDescription
idp_rolevarchar(255)Exact role name from the IDP (e.g., administrators, guest) src/modules/auth/role_mapping_entity.ts:24.
permissionsjsonbArray of permission strings or wildcard patterns src/modules/auth/role_mapping_entity.ts:30.
is_adminbooleanFlag for Admin Bypass. If true, all permission checks are skipped src/modules/auth/role_mapping_entity.ts:33.

Permission Expansion Flow

When a user authenticates, the expandPermissions function resolves the user's IDP roles into a flat set of permission patterns and an isAdmin flag src/modules/auth/permissions.ts:157-160.

Sources: src/modules/auth/role_mapping_entity.ts:18-49, src/modules/auth/permissions.ts:157-179, src/modules/auth/role-mapping-repo.ts:29-44

RBAC Middleware (rbacHandler)

The rbacHandler is the primary interface for securing routes. It orchestrates gateway validation, user authentication, and permission evaluation src/modules/auth/rbac.middleware.ts:4-6.

Logical Semantics

  • OR (Default): User passes if they hold at least one of the declared permissions src/modules/auth/rbac.middleware.ts:87.
  • AND: User must hold all declared permissions. Invoked via rbacHandler.all([...]) src/modules/auth/rbac.middleware.ts:89.

The Evaluation Pipeline

  1. Gateway Check: If AUTH_MODE=GATEWAY, validates the X-Gateway-Secret src/modules/auth/rbac.middleware.ts:120-131.
  2. Auth Check: Skips for PUBLIC, otherwise validates JWT/Headers and populates req.user src/modules/auth/rbac.middleware.ts:140-145.
  3. Admin Bypass: If req.user.isAdmin is true, the request is immediately authorized src/modules/auth/rbac.middleware.ts:172-175.
  4. Pattern Matching: Evaluates req.user.permissions against the route requirements using isPermissionGranted src/modules/auth/rbac.middleware.ts:180-183.

Code-to-System Mapping: Permission Enforcement

Code
graph TD subgraph "Code Entity Space" RH["rbacHandler()"] AM["authMiddleware()"] EP["expandPermissions()"] IPG["isPermissionGranted()"] MW["matchesWildcard()"] end subgraph "Natural Language Space" REQ["Incoming Request"] JWT["JWT (Roles)"] DB["Role Mappings Table"] PASS["Access Granted"] FAIL["403 Forbidden"] end REQ --> RH RH --> AM AM --> JWT JWT --> EP EP --> DB EP --> RH RH --> IPG IPG --> MW MW -- "Match Found" --> PASS MW -- "No Match" --> FAIL

Sources: src/modules/auth/rbac.middleware.ts:92-195, src/modules/auth/permissions.ts:132-146

Wildcard Matching Logic

The system supports the * wildcard to grant access to entire modules or action groups. The matchesWildcard function converts these patterns into Regular Expressions for evaluation src/modules/auth/permissions.ts:116-123.

  • Logic: customers.read.* is converted to /^customers\.read\..*$/ src/modules/auth/permissions.ts:102.
  • Performance: The system first attempts an exact match (fast path) before iterating through wildcard patterns src/modules/auth/permissions.ts:134-136.

Permission Matching Flow

Code
graph LR subgraph "Logic Flow" START["Required: 'customers.read.single'"] EXACT{"Exact Match?"} WILD{"Wildcard Match?"} REG["wildcardToRegex()"] OK["Authorized"] DENY["Forbidden"] end subgraph "Code Entities" P_ENUM["Permission Enum"] U_PERMS["req.user.permissions"] end START --> EXACT U_PERMS --> EXACT EXACT -- "Yes" --> OK EXACT -- "No" --> WILD WILD -- "Iterate patterns" --> REG REG -- "regex.test()" --> OK WILD -- "No matches" --> DENY

Sources: src/modules/auth/permissions.ts:100-123, src/modules/auth/permissions.ts:132-146

Operational Guide: Adding New Permissions

To introduce a new permission to the system, follow these steps:

  1. Define the Constant: Add the new permission string to the Permission object in src/modules/auth/permissions.ts src/modules/auth/permissions.ts:42-87.
  2. Protect the Route: Apply the rbacHandler to the target Express route:
    Code
    router.post("/new-feature", rbacHandler([Permission.NEW_FEATURE_CREATE]), handler);
    src/modules/auth/rbac.middleware.ts:39-43
  3. Update Mappings: Add the permission to the relevant roles in the role_mappings database table using SQL or the RoleMappingRepo.upsertMapping method src/modules/auth/role-mapping-repo.ts:49-54.
  4. Reload: If the application uses a cache for role mappings, restart the server to ensure the RoleMappingRepo loads the latest data AGENTS.md:148.

Sources: src/modules/auth/permissions.ts:16-20, AGENTS.md:139-145, src/modules/auth/role-mapping-repo.ts:49-75


Last modified on July 13, 2026
Project StructureRepository and Query DSL
On this page
  • Permission Registry and Structure
    • Permission Format Examples
    • Permission Sentinels
  • Role Mappings and Expansion
    • Role Mapping Table Structure
    • Permission Expansion Flow
  • RBAC Middleware (rbacHandler)
    • Logical Semantics
    • The Evaluation Pipeline
    • Code-to-System Mapping: Permission Enforcement
  • Wildcard Matching Logic
    • Permission Matching Flow
  • Operational Guide: Adding New Permissions
TypeScript