salvatorecervone/rolepermissionmanager
A modern, dynamic, database-driven Role & Permission Manager for Laravel that completely replaces static middleware annotations with a centralized, zero-hardcoding Access Control Layer (ACL).
In traditional authorization setups, permissions are hardcoded into route definitions, controller constructors, or method calls:
// โ Hardcoded permissions in code
Route::delete('/invoices/{id}', [InvoiceController::class, 'destroy'])
->middleware('permission:delete-invoices');
When business rules change, developers must edit controllers, routes, commit, and deploy.
RolePermissionManager eliminates this entirely:
acl_*) and a non-intrusive dynamic interceptor.permission:... middlewarephp artisan acl:sync scans your routes and registers new endpoints automatically/acl-admin/matrix) with real-time AJAX permission toggling/acl-admin/simulator) and CLI (php artisan acl:check)php artisan acl:export/acl:import)/acl-admin/audit-logs)DynamicAclGuard middleware evaluates requests against cached ACL rules['name', 'cognome']) and live autocomplete@role, @haspermission, @canRoute, and @canResource for views$user->can() and @can^8.2^10.0 | ^11.0 | ^12.0composer require salvatorecervone/rolepermissionmanager
You can publish all assets at once:
php artisan vendor:publish --provider="SalvatoreCervone\RolePermissionManager\RolePermissionManagerServiceProvider"
Or publish individual components using specific tags:
| Component | Publish Command | Target Location |
|---|---|---|
| Config (Required) | php artisan vendor:publish --tag=rolepermissionmanager-config |
config/rolepermissionmanager.php |
| Migrations (Required) | php artisan vendor:publish --tag=rolepermissionmanager-migrations |
database/migrations/ |
| Language Files (Optional) | php artisan vendor:publish --tag=rolepermissionmanager-lang |
lang/vendor/acl/ |
| Blade Views (Optional) | php artisan vendor:publish --tag=rolepermissionmanager-views |
resources/views/vendor/acl/ |
| Routes (Optional) | php artisan vendor:publish --tag=rolepermissionmanager-routes |
routes/acl-web.php & routes/acl-api.php |
php artisan migrate
This creates 8 tables (customizable in config):
acl_rolesacl_permissionsacl_secured_resourcesacl_scanner_rules (dynamic route exclusions & inclusions)acl_model_has_roles (polymorphic pivot)acl_model_has_permissions (polymorphic pivot)acl_role_has_permissions (pivot)acl_permission_has_resources (pivot)acl_audit_logs (audit history)Adding HasAcl to your User model is optional โ it provides direct convenience helper methods on the user instance (e.g., $user->assignRole(), $user->hasPermission(), $user->canAccessRoute()):
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use SalvatoreCervone\RolePermissionManager\Traits\HasAcl;
class User extends Authenticatable
{
use HasAcl;
}
Note: The dynamic middleware
DynamicAclGuard, the Admin Panel, andAclRegistrywork seamlessly even without modifying your User model.
php artisan acl:sync --notify
Output:
๐ Scanning routes...
+-----------------------+--------+----------------------+------------------------------------------------+
| Identifier | Method | URI | Action |
+-----------------------+--------+----------------------+------------------------------------------------+
| dashboard | GET | /dashboard | App\Http\Controllers\DashboardController@index |
| invoices.index | GET | /invoices | App\Http\Controllers\InvoiceController@index |
| invoices.create | GET | /invoices/create | App\Http\Controllers\InvoiceController@create |
| invoices.store | POST | /invoices | App\Http\Controllers\InvoiceController@store |
| invoices.destroy | DELETE | /invoices/{id} | App\Http\Controllers\InvoiceController@destroy |
+-----------------------+--------+----------------------+------------------------------------------------+
โ Discovered 5 new routes. Cache refreshed.
Navigate to https://your-domain.com/acl-admin (protected by ['web', 'auth'] middleware by default).
From the panel you can:
/acl-admin/matrix): Toggle permissions per role in real time./acl-admin/simulator): Select any User and Route to run real-time authorization diagnostics./acl-admin/routes): Select multiple routes to apply permissions or Super Admin flags in bulk./acl-admin/export-import): Download JSON backups or import ACL settings from other environments./acl-admin/audit-logs): Review full historical tracking of authorization changes./acl-admin/users): Assign roles and direct permissions to users with multi-model polymorphic support.If your application has multiple authenticatable models (e.g. User, Admin, Staff), configure user_models in config/rolepermissionmanager.php:
'user_models' => [
'users' => [
'label' => 'Users',
'model' => App\Models\User::class,
'searchable_fields' => ['name', 'email'],
'display_field' => ['name', 'cognome'],
'secondary_field' => 'email',
],
'admins' => [
'label' => 'Administrators',
'model' => App\Models\Admin::class,
'searchable_fields' => ['nome', 'cognome', 'email'],
'display_field' => ['nome', 'cognome'],
'secondary_field' => 'email',
],
],
The Web Admin Panel will automatically render model selector tabs on /acl-admin/users and within the Access Simulator!
/acl-admin/scanner-rules): Manage route exclusions and auto-registration patterns.# 1. Route Synchronization
php artisan acl:sync # Basic route scan and cache rebuild
php artisan acl:sync --clean # Remove deprecated routes from DB
php artisan acl:sync --auto-permissions # Auto-create permissions for new routes
php artisan acl:sync --clean --auto-permissions --notify # Complete sync with verbose log
# 2. Access Diagnostics & Simulation
php artisan acl:check 1 invoices.destroy # Check user ID 1 against a route
php artisan acl:check [email protected] "CorsoController@dettagliocorsi"
# 3. Export & Import Configuration
php artisan acl:export # Export to storage/app/acl-export-*.json
php artisan acl:export --path=/path/to/custom-backup.json
php artisan acl:import /path/to/acl-export.json # Merge configuration
php artisan acl:import /path/to/acl-export.json --overwrite # Overwrite existing associations
{{-- 1. Check Role --}}
@role('admin')
<a href="/admin/settings">Admin Settings</a>
@endrole
{{-- 2. Check Permission (Direct or via Role) --}}
@haspermission('invoices.export')
<button>Export CSV</button>
@endhaspermission
{{-- 3. Check Route Access --}}
@canRoute('invoices.destroy')
<button class="btn-delete">Delete Invoice</button>
@endcanRoute
{{-- 4. Check Custom Resource Access --}}
@canResource('CorsoController@dettagliocorsi')
<button class="btn-info">View Details</button>
@endcanResource
Key settings in config/rolepermissionmanager.php:
return [
// User Model & Search Configuration
'users' => [
'table' => 'users',
'searchable_fields' => ['name', 'cognome', 'email'],
// Single column or array of columns concatenated with space:
'display_field' => ['name', 'cognome'], // e.g. "Mario Rossi"
'secondary_field' => ['matricola', 'email'], // e.g. "MAT12345 [email protected]"
'per_page' => 25,
],
// Super Admin Settings & Bypass
'super_admin' => [
'role' => 'super-admin', // Role slug or null to disable
'all_access' => true, // true / 'all' for full bypass, false/null to require explicit permissions
],
// Middleware settings
'middleware' => [
'register_globally' => true, // Applied to 'web' and 'api' groups
'guard' => null, // null = default guard
'unprotected_behavior' => 'allow', // 'allow' or 'deny'
],
// Automated Scheduler
'scheduler' => [
'enabled' => false,
'time' => '06:00',
'options' => [
'clean' => false,
'auto_permissions' => false,
'notify' => true,
],
],
// Web Admin Panel
'admin_panel' => [
'enabled' => true,
'prefix' => 'acl-admin',
'middleware' => ['web', 'auth'],
'page_title' => 'ACL Manager',
'per_page' => 25,
],
];
Run the test suite:
composer test
# or
./vendor/bin/phpunit
# 1. Run migrations and seed demo data
php vendor/bin/testbench migrate:fresh --seed --class="Workbench\Database\Seeders\DatabaseSeeder"
# 2. Start the local server
php vendor/bin/testbench serve --port=8080
Open http://127.0.0.1:8080 and log in with:
[email protected]passwordThe MIT License (MIT). Please see LICENSE for more information.
How can I help you explore Laravel packages today?