alifcoder / permissions
A simple role and permission management package for Laravel.
Requires
- php: >=8.2
- illuminate/support: ^11.0 || ^12.0 || ^13.0
Requires (Dev)
- laravel/framework: ^v12.14.1
- orchestra/testbench: ^10.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A simple, flexible role and permission management system for Laravel applications โ designed to support
Gate::before, SUPER ADMIN logic, modular apps (nwidart/laravel-modules), and dynamic user model resolution.
โจ Features
- Role and permission management with pivot tables
SUPER ADMINbypass support usingGate::before()HasRolesTraittrait for easy user integration- Every role and permission check is answered from memory โ one query per user, per request
- Automatic cache invalidation on every role/permission change
- Dynamically configurable role and permission models (UUID or auto-increment keys)
- Language file localization (EN, customizable)
- Clean service provider with publishable config and migrations
- Works with modular Laravel apps (like
nwidart/laravel-modules)
๐ฆ Requirements
- PHP
>=8.2 - Laravel
^11.0 || ^12.0 || ^13.0
๐ Installation
composer require alifcoder/permissions
Then publish the config, translations, and migrations:
php artisan vendor:publish --tag=permissions php artisan migrate
This will publish:
lang/vendor/permissionsconfig/permission.phpdatabase/migrations/xxxx_xx_xx_xxxxxx_create_permissions_table.php
โ๏ธ Configuration
Inside config/permissions.php:
return [ 'models' => [ 'role' => \Alif\Permissions\Models\Role::class, 'permission' => \Alif\Permissions\Models\Permission::class, ], // cache the roles and permissions of every user 'cacheable' => true, // cache store used by the package (null = default store) 'cache_store' => null, // lifetime in seconds of a cached entry (null = forever) 'cache_ttl' => null, // set to false when your primary keys are auto-incrementing integers 'is_model_uuid' => true, ];
You can override the role and permission models here.
โ ๏ธ Caching requires a cache store that supports tags (
redis,memcached,array). When the store is not taggable the package keeps working, it simply reads from the database.
๐งฌ Traits
In your User model, add the trait:
use Alif\Permissions\Traits\HasRolesTrait; class User extends Authenticatable { use HasRolesTrait; }
๐ Super Admin Access
Add this in your app (e.g., AuthServiceProvider) โ or it's auto-registered by the package:
Gate::before(function ($user) { // $user is null on guest checks return $user !== null && $user->isSuperAdmin() ? true : null; });
This lets SUPER ADMIN users bypass all policy/gate checks, and the role / permission middleware.
๐ง Usage
Assign Roles & Permissions
$admin = Role::create(['name' => 'Admin', 's_code' => 'admin']); $edit = Permission::create(['name' => 'products.update']); // role <-> permissions (these methods keep the cache in sync) $admin->givePermissionTo($edit); // model, id or name $admin->syncPermissions(['products.update', 'products.read']); $admin->revokePermissionTo('products.read'); // user <-> roles (these methods keep the cache in sync) $user->assignRoles('admin'); // add, keeps the existing roles $user->syncRoles([$admin, 'manager']); // replace $user->removeRole($admin->id); // detach
Every method accepts a model, a primary key, a role name, a role s_code, or an array/collection of them.
โ ๏ธ
$user->roles()->attach()/$role->permissions()->attach()bypass the package, so they leave a stale cache behind. Use the methods above, or call$user->forgetPermissionCache()/$role->forgetPermissionCache()yourself afterwards.
Check Roles & Permissions
$user->hasAllRoles('admin'); // true $user->hasAnyRole(['admin', 'manager']); // true $user->hasAllPermissions(['products.update']); // true $user->hasAnyPermission('products.update'); // true $user->isSuperAdmin(); // true or false $user->roles; // roles of the user, with their permissions (cached) $user->permissions; // unique permissions of all roles (cached) $user->permissionNames(); // the same, as a plain array of names
All checks above are resolved in memory: the roles of a user are read once (from the cache when it is enabled, otherwise with a single query) and every following check reuses them.
Cache invalidation
The cache is dropped automatically when:
| Change | What is dropped |
|---|---|
assignRoles(), syncRoles(), removeRole() |
the cache of that user |
| the user is deleted | the cache of that user |
givePermissionTo(), syncPermissions(), revokePermissionTo() |
the whole package cache |
| a role is updated, deleted or restored | the whole package cache |
| a permission is updated or deleted | the whole package cache |
๐ Localization
The package includes English (en) translations. To override or translate:
Then add resources/lang/vendor/permissions/{locale}/permissions.php.
๐งโ๐ป Usage macro
Also you can use Route macro to check permissions and roles:
Route::put('/products/{product}', function () { // Your logic here })->permission('products.update'); Route::put('/admin', function () { // Your logic here })->role('admin'); // or the middleware aliases directly, an optional second argument selects the guard Route::put('/admin', fn() => null)->middleware('role:admin|manager,web');
โ ๏ธ Several roles/permissions are checked with AND:
role:admin|managerrequires both roles.
๐งฉ Folder Structure
src/
โโโ Models/
โ โโโ Concerns/
โ โโโ Role.php
โ โโโ Permission.php
โโโ Traits/
โ โโโ HasRolesTrait.php
โโโ Support/
โ โโโ PermissionCache.php
โโโ Middleware/
โโโ Macros/
โโโ Exceptions/
โโโ Helpers/
โโโ Console/
โโโ PermissionServiceProvider.php
config/
โโโ permissions.php
resources/
โโโ lang/en/permissions.php
database/
โโโ migrations/
๐งน Clear permission caches
Run this command to clear the permission cache:
php artisan permission:cache-clear
๐งน Uninstall (Clean Up)
Run this command before removing the package:
php artisan permission:uninstall
It rolls back the migration, deletes the published files and clears the cache. In production it asks for a
confirmation, use --force to skip it.
๐งช Tests
composer install
composer test
The suite runs against orchestra/testbench with an in-memory SQLite database, and covers both UUID and
auto-incrementing primary keys, the cache invalidation matrix, the middlewares and the console commands.
๐ License
MIT ยฉ Shukhratjon Yuldashev
๐ Contributing
Pull requests and suggestions are welcome!