VOOZH about

URL: https://deepwiki.com/mathsgod/light/5.5.2-permission-checking

⇱ Permission Checking | mathsgod/light | DeepWiki


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

Permission Checking

Purpose and Scope

This document describes how the Light framework enforces authorization through its permission checking system. It covers the annotation-based authorization mechanisms (@Logged and @Right attributes), dynamic permission discovery through reflection, runtime permission verification, and menu-based authorization.

For information about the underlying RBAC system architecture, role definitions, and role hierarchy, see Role Hierarchy and Permissions. For authentication mechanisms and user identity establishment, see Authentication Architecture.


Overview of Permission Enforcement

The Light framework implements a multi-layered permission checking system that enforces authorization at three distinct levels:

LayerMechanismScopeExample
GraphQL Field Level@Right annotationIndividual query/mutation fields#[Right("user.list")]
Authentication Level@Logged annotationRequires authenticated user#[Logged]
UI Navigation LevelMenu permissionsControls menu visibilitypermission: user.list

All permission checks integrate with the Light\Rbac\Rbac system to verify whether the authenticated user's roles grant access to the requested resource.

Sources: src/App.php392-472 src/Type/App.php191-261


Annotation-Based Authorization

The @Logged Annotation

The @Logged annotation enforces that a user must be authenticated to access a GraphQL field. It does not check specific permissions, only that a valid JWT token is present and the user exists in the system.

Usage Pattern:


When GraphQLite processes a request, it invokes the Auth\Service (configured via SchemaFactory::setAuthenticationService()) to verify authentication before executing the resolver. If authentication fails, the field returns an error.

Sources: src/Type/App.php33-36 src/Type/App.php187-202 src/App.php529-530

The @Right Annotation

The @Right annotation declares that a specific permission is required to access a GraphQL field. The annotation accepts a permission string that is checked against the user's roles.

Usage Pattern:


The permission string is hierarchical and typically follows the pattern resource.action (e.g., user.list, role.add, config.update). The GraphQLite authorization service (also Auth\Service) checks if the user's roles include this permission.

Common Permission Patterns:

PatternExampleDescription
resource.actionuser.listStandard resource-action permission
resource.subresource.actionsystem.database.backupHierarchical resource permission
Wildcard*Administrator catch-all permission
Role marker#administratorsInternal role membership marker

Sources: src/Type/App.php342-350 src/Type/App.php460-473 src/App.php399-401

Combined Usage

Fields frequently combine both annotations to enforce authentication and authorization:


This pattern ensures the user is authenticated (@Logged) and has the config permission (@Right).

Sources: src/Type/App.php341-350


Permission Discovery Process

The Light framework dynamically discovers all permissions defined in the codebase by scanning for @Right annotations using reflection. This enables the system to present a complete list of available permissions for administrative purposes.

Discovery Algorithm

The App::getPermissions() method performs a multi-stage scan:


Scanning Implementation:

The scan examines each method in discovered classes and extracts the first argument from @Right attributes:


This reflection-based approach occurs at these locations:

  • /src/Controller/*.php - GraphQL controller mutations
  • /src/Model/*.php - Model-level permissions
  • /src/Database/*.php - Database operation permissions
  • /src/Type/*.php - GraphQL type field permissions
  • Composer-registered Controller and Model namespaces (for plugins)

Sources: src/App.php392-472

Menu Permission Extraction

The system also extracts permissions from menu definitions recursively:


This collects permissions from both menus.yml and custom menus stored in the Config model.

Sources: src/App.php368-390 src/App.php453-455


Runtime Permission Verification

Integration with GraphQLite

During request processing, the App class configures the GraphQLite schema factory with the Auth\Service instance, which implements both authentication and authorization interfaces:


The authorization check occurs before each resolver method executes, ensuring permissions are enforced at the GraphQL schema level.

Sources: src/App.php526-536

Role-Based Permission Checking

The Rbac class manages the relationship between users, roles, and permissions. Permission verification follows this logic:

  1. Check wildcard permission: Administrators with * permission bypass all checks
  2. Check role permissions: Iterate through user's roles and check if any role has the required permission
  3. Check user-specific permissions: Direct user permissions override role-based permissions

The implementation in menu filtering demonstrates this pattern:


Sources: src/Type/App.php244-249


Menu-Based Authorization

Menu Permission Declarations

Menus declare required permissions in YAML configuration. The system supports both single permissions and arrays of permissions:

Single Permission:


Multiple Permissions (OR logic):


When multiple permissions are specified, the user needs only ONE of them to access the menu item.

Sources: menus.yml4-15 menus.yml42-45

Menu Filtering Algorithm

The App::getMenus() method filters the menu tree based on the authenticated user's roles and permissions:


The filtering logic handles special cases:

  • Role markers: Permissions starting with # (e.g., #administrators) check direct role membership rather than RBAC permissions
  • Nested menus: Parent menus without direct links are hidden if all children are filtered out
  • Multiple permissions: If an array of permissions is provided, access is granted if the user has ANY of them

Sources: src/Type/App.php197-261

Special Permission Syntax

SyntaxExampleMeaning
resource.actionuser.listStandard permission check via RBAC
#rolename#administratorsDirect role membership check
[perm1, perm2][user.read, user.list]OR logic - user needs any one

The # prefix indicates an internal role marker that bypasses RBAC permission checking and directly verifies role membership:


This allows menu items to be restricted to specific role groups without defining explicit permissions.

Sources: src/Type/App.php236-241


Wildcard Permissions

Administrator Wildcard

The Administrators role is granted a wildcard permission (*) that matches all permission checks:


This wildcard bypasses all specific permission checks, granting unrestricted access to administrators. The RBAC system evaluates this during permission verification.

Sources: permissions.yml1-2

Role Hierarchy Wildcards

Role markers (prefixed with #) are automatically added to roles during RBAC loading. These serve as membership flags:


These special permissions allow menu items and features to be restricted to specific roles without explicit permission strings.

Sources: src/App.php309-313


Permission Storage and Loading

Multi-Source Permission Architecture

Permissions are loaded from three distinct sources during application initialization:


Loading Sequence

The App::loadRbac() method executes during application initialization and loads permissions in this order:

1. System Roles (Hardcoded):


2. Database Role Hierarchy:


3. YAML Permission Definitions:


4. Database Permissions:


5. User-Role Associations:


This loading order ensures that database-stored permissions can override YAML definitions, and user-specific permissions take precedence over role-based permissions.

Sources: src/App.php306-366

Permission Model Structure

The Permission database model stores dynamic permissions with three possible assignments:

FieldTypeDescription
permission_idINTPrimary key
roleVARCHARRole name (if role-based permission)
user_idINTUser ID (if user-specific permission)
valueVARCHARPermission string (e.g., "user.list")

Permissions can be assigned either to a role (affecting all users with that role) or directly to a specific user (overriding role permissions).

Sources: src/App.php345-355


Permission Checking Reference

Common Permission Patterns in Codebase

Permission StringResourceActionUsed In
user.listUserList userssrc/Type/App.php460
user.addUserCreate userpermissions.yml7
user.deleteUserDelete userpermissions.yml8
user.updateUserUpdate userpermissions.yml9
role.listRoleList rolessrc/Type/App.php482
configConfigAccess configsrc/Type/App.php343
permission.listPermissionList permissionssrc/Type/App.php535
maillog.listMailLogList mail logssrc/Type/App.php416
eventlog.listEventLogList event logssrc/Type/App.php427
filesystem.listFileSystemList filesystemssrc/Type/App.php501

GraphQL Field Protection Examples

Query Field with Permission:


Mutation Field with Permission:


Authentication Only (No Specific Permission):


Sources: src/Type/App.php460-473 src/Type/App.php342-350 src/Type/App.php197-202