VOOZH about

URL: https://deepwiki.com/mathsgod/light/3.4-rbac-integration

⇱ RBAC Integration | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

RBAC Integration

Purpose and Scope

This document explains how the Light\App class initializes, configures, and manages the Role-Based Access Control (RBAC) system during application startup. It covers the role hierarchy construction, permission loading from multiple sources (YAML files, database records, menu definitions, and GraphQL annotations), and dynamic permission discovery via reflection.

For details on how RBAC permissions are enforced at runtime through annotations and authorization checks, see Permission Checking. For information about the RBAC system's internal structure and API, see RBAC System.


RBAC Initialization in App Constructor

The RBAC system is instantiated early in the App class constructor, immediately after setting up the dependency injection container and GraphQL schema factory. The initialization follows a specific sequence to ensure all permission sources are loaded before the application begins processing requests.


RBAC Initialization Flow

The RBAC instance is stored in the App class's $rbac protected property and later registered in the DI container, making it accessible to controllers, type resolvers, and the authentication service.

Sources: src/App.php128-129 src/App.php365


Role Hierarchy Construction

The loadRbac() method establishes a four-tier default role hierarchy with inheritance relationships, ensuring that higher-level roles automatically inherit permissions from lower-level roles.


Default Role Hierarchy with Inheritance

Default Role Creation

The four default roles are created with special hash-prefixed permissions that identify role membership:

RolePermissionInherits From
Administrators#administratorsNone (top-level)
Power Users#power usersAdministrators
Users#usersPower Users
Everyone#everyoneUsers

Each role automatically gains access to all permissions granted to its child roles through the inheritance chain. This is established through the addParent() method calls.

Sources: src/App.php308-322

Database-Defined Roles

After creating the default hierarchy, the system loads additional roles from the Role database model. Each Role record defines a parent-child relationship between two roles:


Database Role Processing Flow

The system iterates through all Role records and establishes parent-child relationships using addChild(). Both parent and child roles receive hash-prefixed permissions for role identification.

Sources: src/App.php324-334


Permission Loading from Multiple Sources

The RBAC system aggregates permissions from four distinct sources, processed in a specific order to build a complete permission map.


Permission Aggregation Architecture

YAML-Based Permissions

The permissions.yml file defines static role-permission mappings that apply to all application instances. This is the first source loaded:


The wildcard permission '*' for Administrators grants access to everything, while other roles receive explicit permission lists. These are loaded and assigned to roles via addRolePermissions():

Sources: src/App.php338-343 permissions.yml1-15

Database Permissions

The Permission model stores runtime-configurable permissions that can be assigned to either roles or individual users:

FieldTypePurpose
rolestringRole to grant permission to
user_idintegerUser to grant permission to
valuestringPermission string (e.g., "user.delete")

The loading logic handles both role-based and user-based permissions:


Database Permission Assignment Logic

This allows permissions to be granted at both the role level (affecting all users with that role) and the user level (affecting only specific users).

Sources: src/App.php345-355

UserRole Assignments

The UserRole model maps users to roles, establishing which permissions each user inherits:


UserRole Processing Pipeline

Each UserRole record ensures the role exists in the RBAC system, assigns the specified user to that role, and adds the hash-prefixed role identifier permission.

Sources: src/App.php357-363


Dynamic Permission Discovery

The getPermissions() method performs comprehensive permission discovery by scanning PHP classes for @Right annotations. This enables centralized visibility into all permissions defined throughout the codebase.


Comprehensive Permission Discovery Process

Annotation Scanning Strategy

The discovery process uses PHP reflection to inspect class methods for TheCodingMachine\GraphQLite\Annotations\Right attributes. The scanning covers:

  1. System directories: Light\Controller\*, Light\Model\*, Light\Database\*, Light\Type\*
  2. Extension namespaces: Any classes in Controller\* or Model\* namespaces discovered by ComposerFinder

For each class found, the system:

  • Creates a ReflectionClass instance
  • Iterates through all methods via getMethods()
  • Retrieves @Right attributes via getAttributes()
  • Extracts the permission string from getArguments()[0]

Sources: src/App.php392-451

Menu Permission Extraction

The getMenusPermission() method recursively traverses the menu tree to extract permission requirements:


Recursive Menu Permission Extraction

Menu items can have either a single permission string or an array of permissions. The method handles both cases and recursively processes child menu items.

Sources: src/App.php368-390

Permission Aggregation and Filtering

After collecting permissions from all sources, the system performs cleanup:

  1. Hash filtering: Removes permissions starting with # (internal role identifiers)
  2. Deduplication: Uses array_unique() to eliminate duplicates
  3. Sorting: Alphabetically sorts the final list via sort()

This produces a clean, ordered list of all discoverable permissions that can be displayed in administrative interfaces.

Sources: src/App.php462-471


RBAC Service Registration

Once fully configured, the RBAC instance is registered in the dependency injection container, making it available throughout the application:


RBAC Service Distribution

The RBAC service can be accessed via:

  • Dependency injection: Controllers and services receive it automatically via constructor injection
  • App accessor: The App::getRbac() method provides direct access to the instance
  • Auth service: The authentication service uses RBAC for permission checks during GraphQL field resolution

Sources: src/App.php365 src/App.php480-483


Helper Methods for RBAC Management

The App class provides utility methods for programmatic RBAC manipulation:

addRolePermissions()

Adds multiple permissions to a role, creating the role if it doesn't exist:


This method:

  1. Checks if the role exists via rbac->hasRole()
  2. Creates the role if missing via rbac->addRole()
  3. Retrieves the role object via rbac->getRole()
  4. Adds each permission via role->addPermission()

Sources: src/App.php294-304

getRbac()

Returns the configured RBAC instance for direct access:


This provides access to the full RBAC API, including permission checking methods like isAllowed() and role management methods.

Sources: src/App.php480-483


Integration with GraphQL Authorization

The RBAC system is connected to the GraphQL schema factory to enable field-level authorization. During request processing, the authentication service is set as both the authentication and authorization service:


This integration allows GraphQLite's @Right and @Logged annotations to query the RBAC system for permission checks before resolving GraphQL fields.

Sources: src/App.php529-530


Summary

The RBAC integration in Light\App creates a sophisticated, multi-source permission system:

ComponentPurposeKey Method
Role HierarchyFour-tier inheritance structureloadRbac() lines 308-322
YAML PermissionsStatic role definitionsloadRbac() lines 338-343
Database PermissionsRuntime-configurable grantsloadRbac() lines 345-355
UserRole MappingsUser-to-role assignmentsloadRbac() lines 357-363
Menu PermissionsNavigation-based authorizationgetMenusPermission()
Annotation DiscoveryGraphQL field permissionsgetPermissions()
Container RegistrationDI system integrationLine 365

This layered approach provides flexibility for both compile-time permission definitions (YAML, annotations) and runtime permission management (database records), while maintaining a clear hierarchy through role inheritance.

Sources: src/App.php59-366 permissions.yml1-15 menus.yml1-171