codeflextech/permission-manager
Plug-and-play Roles & Permissions management UI for Laravel 11 using spatie/laravel-permission + Livewire 3. Permission/role CRUD, grouped permission matrix, assign roles to users, dashboard stats, super admin protection, standalone CSS, configurable routes/middleware/guard.
Installation
Run composer require codeflextech/permission-manager and publish the config (php artisan vendor:publish --tag=permission-manager-config) and CSS (php artisan vendor:publish --provider="CodeFlexTech\PermissionManager\PermissionManagerServiceProvider" --tag=permission-manager-assets).
Run Migrations
Execute php artisan migrate to set up the required tables (permissions, roles, model_has_permissions, model_has_roles).
Configure Middleware
Add the permission-manager middleware to your routes (e.g., Route::middleware(['auth', 'permission-manager'])->group(...)) or use the default guard in the config.
First Access
Visit /permission-manager (or your configured route prefix) to access the dashboard. The UI will auto-detect permission groups from your existing spatie/laravel-permission setup.
Quick Action
Create a new role (e.g., "Editor") and assign permissions like posts.create or users.edit via the visual checkbox matrix.
/permission-manager – Overview of roles, permissions, and user counts./permission-manager/permissions – Manage individual permissions with dot-notation grouping./permission-manager/roles – Create/edit roles with bulk permission assignment.config/permission-manager.php – Adjust middleware, guards, or route prefixes.posts.*).posts.*).posts.create auto-group under "posts" in the UI./permission-manager/users/{id}/roles endpoint (if integrated with Laravel’s user model).@can('permission-manager.access') or via middleware:
Route::middleware(['auth', 'permission-manager'])->group(function () {
// Admin-only routes
});
config/permission-manager.php:
'guard' => 'admin', // Use a custom guard (e.g., Sanctum, Passport)
php artisan vendor:publish --tag=permission-manager-views
Key files: resources/views/vendor/permission-manager/layouts/app.blade.php.public/css/permission-manager.css.PermissionGroup class or hooking into the grouping event.spatie/laravel-permission methods in your controllers:
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
// Example: Create a permission programmatically
Permission::create(['name' => 'reports.export']);
// Assign a role to a user
$user->assignRole('Content Manager');
/permission-manager in the Nova menu.use CodeFlexTech\PermissionManager\Livewire\PermissionMatrix;
// In your Livewire component
public PermissionMatrix;
spatie/laravel-permission helpers:
$user->givePermissionTo('posts.create');
$this->assertTrue($user->hasPermissionTo('posts.create'));
$this->livewire(PermissionMatrix::class)
->set('selectedPermissions', ['posts.create'])
->assertSee('posts.create');
CSS Conflicts
.permission-group, .role-card).Super Admin Lock
canDeleteRole method in the Role model or publish the views and modify the delete button logic.Permission Grouping Logic
posts.create → group "posts"). If your permissions use a different delimiter (e.g., posts:create), you’ll need to extend the PermissionGroup class or override the grouping logic in the config:
'permission_group_delimiter' => ':', // Custom delimiter
Livewire Caching
php artisan view:clear
php artisan cache:clear
Middleware Timing
permission-manager middleware is registered after the auth middleware in your HandleIncomingRequests middleware group. Misordering can cause infinite redirects.User Model Assumptions
Spatie\Permission\Traits\HasRoles and HasPermissions. If you’re using a custom trait, update the config:
'user_model' => App\Models\CustomUser::class,
Log Permission Groups
Add this to your AppServiceProvider to debug grouping:
use CodeFlexTech\PermissionManager\Services\PermissionGroup;
public function boot()
{
PermissionGroup::macro('logGroups', function () {
\Log::info('Permission Groups:', [
'groups' => PermissionGroup::getGroups()
]);
});
}
Check Livewire Events Enable Livewire logging to debug component interactions:
LIVEWIRE_LOG=1 php artisan serve
Verify Middleware Test middleware isolation by temporarily removing it and checking if routes are accessible:
// Temporarily disable in routes.php
Route::middleware(['auth'])->group(...); // Remove 'permission-manager'
Custom Permission Groups
Extend the PermissionGroup class to support custom grouping logic:
namespace App\Services;
use CodeFlexTech\PermissionManager\Services\PermissionGroup as BasePermissionGroup;
class CustomPermissionGroup extends BasePermissionGroup
{
public function getGroupForPermission(string $permission): string
{
// Custom logic (e.g., split by '::' instead of '.')
return explode('::', $permission)[0];
}
}
Then bind it in AppServiceProvider:
$this->app->bind(
\CodeFlexTech\PermissionManager\Contracts\PermissionGroup::class,
App\Services\CustomPermissionGroup::class
);
Add Custom Fields to Roles
Extend the Role model and update the Livewire components:
// app/Models/Role.php
use Illuminate\Database\Eloquent\Relations\HasMany;
public function customFields(): HasMany
{
return $this->hasMany(RoleCustomField::class);
}
Publish the views and add the fields to the RoleCreateEdit Livewire component.
API-Only Usage
Disable the UI and use the underlying spatie/laravel-permission methods directly. Set this in config:
'enable_ui' => false,
Multi-Guard Support Extend the package to support multiple guards (e.g., web + api) by overriding
How can I help you explore Laravel packages today?