Overview
SushiGo uses Spatie Laravel Permission for role-based access control (RBAC). The permission system operates on the User model (not Employee) with theapi guard for Laravel Passport integration.
Core Principle
Permission Model
Database Tables
Spatie Permission creates these tables:roles- Role definitionspermissions- Permission definitionsmodel_has_roles- User → Role assignmentsmodel_has_permissions- User → Direct permission assignmentsrole_has_permissions- Role → Permission mappings
System Roles
All roles operate on theapi guard and are assigned to User models.
System-Level Roles
| Role | Employee Profile | Description | Base Permissions |
|---|---|---|---|
super-admin | ❌ No | Full system access. Technical account. | All (*) |
admin | ✅ Yes | Full operational management. | users.*, employees.*, items.*, inventory.* |
inventory-manager | ✅ Yes | Inventory and team management. | users.*, employees.*, items.*, stock.* |
employee-manager | ✅ Yes | Team lead. Auto-assigned via position sync. | users.index, users.show, employees.* |
employee | ✅ Yes | Base access for active employees. | users.index, users.show |
user | ⚪ Optional | Generic fallback for non-employee accounts. | users.index, users.show |
Position Roles
Position roles reflect the employee’s job title. They are assigned to the User when syncing position roles viaEmployee::syncPositionRoles().
Available positions:
| Position Role | Resulting System Role | Capabilities |
|---|---|---|
manager | employee-manager | Team management |
cook | employee | Base employee access |
kitchen-assistant | employee | Base employee access |
delivery-driver | employee | Base employee access |
acting-manager | employee | Base employee access |
admin | admin | Full operational access |
super-admin | super-admin | Full system access |
Permission Structure
Permissions follow theresource.action naming convention:
Common Patterns
Permission Checking
In controllers:Role Assignment
Creating a User with Role
Employee Position Sync
When creating or updating an Employee, position roles are synced to the linked User:- Preserves system roles (
admin,inventory-manager, etc.) - Only replaces position roles (
manager,cook, etc.) - Respects acting user’s permission level (non-super-admins cannot assign
super-admin)
Direct Permission Assignment
In addition to roles, users can have direct permissions:- Temporary access grants
- Fine-grained exceptions to role policies
- Audit/investigative access
Employee Creation Flow
When creating an employee, roles flow from Employee to User: From the codebase:Operating Unit Roles
In addition to system-wide roles, users can have contextual roles per Operating Unit via theoperating_unit_users pivot table:
Assignment Roles
| Role | Description |
|---|---|
OWNER | Full control over the operating unit |
MANAGER | Operational management, reporting |
CASHIER | Sales and cash operations |
INVENTORY | Stock management and counts |
AUDITOR | Read-only access for audits |
Operating Unit assignment roles are separate from system roles. A user might be:
- System role:
employee(minimal global access) - Operating Unit role:
MANAGER(full control within that unit)
Permission Seeders
Roles and permissions are created via seeders:RoleSeeder
PermissionSeeder
RoleSeeder- Create all rolesPermissionSeeder- Create permissions + assign to rolesUserSeeder- Create admin usersUserRoleSeeder- Assign system roles to users
Privileged Role Protection
Only super-admins can assign thesuper-admin role:
- Super-admins can assign all roles (including
super-admin) - Other users cannot assign
super-adminrole - Prevents privilege escalation
Checking Permissions in Frontend
The webapp receives user roles in the login response:Wildcard Permissions
Spatie Permission supports wildcard permissions:Best Practices
Role vs Direct Permission
Role vs Direct Permission
Use roles for:
- Permanent access patterns
- Job-based permissions
- Grouping related permissions
- Temporary grants
- Exceptions to role policies
- Fine-grained access control
Position Role Management
Position Role Management
- Always use
syncPositionRoles()to update employee positions - Never directly call
User::syncRoles()for employees - Let the Employee model handle preservation of system roles
- Log all role changes for audit trail
Permission Naming
Permission Naming
- Use
resource.actionformat - Keep names lowercase with dots
- Use wildcards sparingly (admin roles only)
- Document new permissions in PermissionSeeder
Testing Permissions
Testing Permissions
- Test both role-based and direct permissions
- Verify privilege escalation protection
- Test permission inheritance from roles
- Check operating unit role isolation
Common Permission Patterns
Resource CRUD
Hierarchical Checks
Context-Aware Permissions
Troubleshooting
Permission Not Recognized
Cause: Permission not seeded or cache not cleared Solution:Role Changes Not Applied
Cause: Spatie Permission caches role/permission data Solution:User Has Role But Permission Check Fails
Cause: Guard mismatch (usingweb guard instead of api)
Solution:
Related Documentation
Authentication
OAuth2 token-based auth
User Management
Creating and managing users
Operating Units
Operating unit assignments
System Architecture
Overall system design