A 100% database-driven, automated role-permission system for Laravel with zero-code setup.
- 🎯 Zero-Code Setup: No middleware in routes or controllers - everything is automatic
- 🔄 Global Auto-Enforcement: Enable once, all routes are protected automatically
- 🛠️ Complete REST API: Manage everything through API/UI without touching code
- 🔍 Auto-Discovery: Automatically scan and sync permissions from your controllers
- ⚡ Dynamic Management: Create roles, assign permissions, manage users - all in real-time
- 🔒 Multi-Guard Support: Support for multiple authentication guards (web, api, etc.)
- 📊 Granular Permissions: Module + Action based permission system
- 🎨 Admin-Friendly: Build any admin UI with provided API endpoints
Perfect for projects where admins manage permissions through a UI without touching code.
👉 Read DYNAMIC_SETUP.md for the complete guide
Quick Overview:
# Just add this to .env
ENABLE_GLOBAL_PERMISSION_MIDDLEWARE=true- ✅ No middleware in routes - Everything automatic
- ✅ Complete REST API - Build any admin UI
- ✅ Database-driven - Users control everything
- ✅ Zero code changes - Add controllers, sync, done!
For projects where you want more control and explicit permission definitions.
👉 Continue reading this README for traditional setup
Create a packages folder in your project root and clone this repository:
mkdir packages
cd packages
git clone https://github.com/imtiaz-kolpolok/role-based-access-control.gitAdd the following to your composer.json:
{
"require": {
"kiurd/role-based-access-control": "dev-master"
},
"repositories": [
{
"type": "path",
"url": "./packages/role-based-access-control"
}
]
}composer updatephp artisan vendor:publish --tag=role-permissions-config
php artisan vendor:publish --tag=role-permissions-migrations
php artisan migrateAdd the HasRolesAndPermissions trait to your User model:
use Kiurd\RolePermissions\Traits\HasRolesAndPermissions;
class User extends Authenticatable
{
use HasRolesAndPermissions;
// ... rest of your model
}The package can automatically scan your controllers and create permissions:
# Preview what will be synced (recommended first)
php artisan permissions:sync --preview
# Sync from routes
php artisan permissions:sync --source=routes
# Sync from controllers directory
php artisan permissions:sync --source=controllers
# Sync with specific guard
php artisan permissions:sync --guard=api
# Sync from custom path
php artisan permissions:sync --source=controllers --path=/path/to/controllersHow it works:
- Scans your controllers and extracts public methods
- Converts controller names to module names (e.g.,
UserController→users) - Maps methods to actions (e.g.,
store→create,index→list) - Automatically creates modules, actions, and permissions in your database
The package automatically maps controller methods to permission actions:
| Controller Method | Permission Action |
|---|---|
index() |
list |
show() |
read |
create() |
create |
store() |
create |
edit() |
update |
update() |
update |
destroy() |
delete |
delete() |
delete |
| Other methods | snake_case of method name |
You can customize this mapping in config/role_permissions.php.
php artisan role:create admin --description="Administrator role"
php artisan role:create editor --guard=api# Assign single permission (auto-creates module and action if needed)
php artisan role:assign-permission admin users create
php artisan role:assign-permission editor posts update --guard=webAssign multiple permissions at once instead of one by one:
# Assign ALL permissions to a role
php artisan role:assign-all-permissions super-admin
# Assign all permissions for a specific module
php artisan role:assign-all-permissions manager --module=users
# Assign all permissions for a specific action across all modules
php artisan role:assign-all-permissions reader --action=read
# Combine filters: all 'create' permissions for 'users' module
php artisan role:assign-all-permissions editor --module=users --action=create
# Skip confirmation prompt
php artisan role:assign-all-permissions admin --force
# With specific guard
php artisan role:assign-all-permissions admin --guard=apiExample Output:
🎭 Role: manager
📋 Permissions to be assigned (4):
📦 users
• create
• read
• update
• delete
🔍 Filters applied: Module: users
✅ Permissions assigned successfully!
+----------------------------+-------+
| Status | Count |
+----------------------------+-------+
| Newly assigned | 4 |
| Already assigned | 0 |
| Total permissions for role | 4 |
+----------------------------+-------+
# List all permissions
php artisan permissions:list
# Filter by role
php artisan permissions:list --role=admin
# Filter by module
php artisan permissions:list --module=users
# Filter by guard
php artisan permissions:list --guard=apiFind out which roles and permissions are assigned to a specific user:
# By user ID
php artisan user:show 1
# By email
php artisan user:show [email protected]
# With specific guard
php artisan user:show 1 --guard=apiExample Output:
👤 User Information
ID: 1
Name: John Doe
Email: [email protected]
🎭 Roles (2)
+----+---------+-------------------------+
| ID | Role | Description |
+----+---------+-------------------------+
| 1 | admin | Administrator role |
| 2 | editor | Content editor |
+----+---------+-------------------------+
🔐 Permissions (15)
📦 users
• create
• read
• update
• delete
📦 posts
• create
• update
📦 products
• read
✅ Summary:
• 2 role(s)
• 15 permission(s)
• 3 module(s)
Find out which permissions belong to a role and which users have that role:
# By role name
php artisan role:show admin
# By role ID
php artisan role:show 1
# Include users with this role
php artisan role:show admin --with-users
# With specific guard
php artisan role:show admin --guard=webExample Output:
🎭 Role Information
ID: 1
Name: admin
Description: Administrator role
Guard: web
🔐 Permissions (12)
📦 users
• create (ID: 1)
• read (ID: 2)
• update (ID: 3)
• delete (ID: 4)
📦 posts
• create (ID: 5)
• update (ID: 6)
• delete (ID: 7)
👥 Users with this role (3)
+----+------------+---------------------+
| ID | Name | Email |
+----+------------+---------------------+
| 1 | John Doe | [email protected] |
| 2 | Jane Smith | [email protected] |
| 3 | Bob Wilson | [email protected] |
+----+------------+---------------------+
✅ Summary:
• 12 permission(s)
• 2 module(s)
• 3 user(s)
Find out which actions (permissions) belong to a module and which roles have access:
# By module name
php artisan module:show users
# By module ID
php artisan module:show 1
# Include roles with access
php artisan module:show users --with-roles
# With specific guard
php artisan module:show users --guard=webExample Output:
📦 Module Information
ID: 1
Name: users
Description: User management module
Guard: web
🔐 Available Actions (5)
+---------------+--------+------------------+
| Permission ID | Action | Description |
+---------------+--------+------------------+
| 1 | create | Create operation |
| 2 | read | Read operation |
| 3 | update | Update operation |
| 4 | delete | Delete operation |
| 5 | list | List operation |
+---------------+--------+------------------+
🎭 Roles with access to this module (3)
• admin → create, read, update, delete, list
• editor → read, update
• viewer → read, list
✅ Summary:
• 5 action(s) available
• 3 role(s) have access
Automatically discovers and checks permissions based on the controller and method:
// In your routes or controller constructor
Route::middleware(['auth', 'permission.auto'])->group(function () {
Route::resource('users', UserController::class);
});
// Or in controller constructor
public function __construct()
{
$this->middleware('permission.auto');
}Auto-Create Permissions: Enable in .env to automatically create permissions on first access:
AUTO_CREATE_PERMISSIONS=trueCheck specific module and action permissions:
// Simple permission check
Route::middleware(['auth', 'permission:users,create'])->group(function () {
Route::post('/users', [UserController::class, 'store']);
});
// Method-based permission mapping
Route::middleware(['auth', 'permission.check:users,create:store|update:update|delete:destroy'])
->group(function () {
Route::resource('users', UserController::class);
});// Check if user has a role
if (auth()->user()->hasRole('admin')) {
// User is admin
}
// Check multiple roles (OR logic)
if (auth()->user()->hasRole(['admin', 'editor'])) {
// User has admin OR editor role
}
// Get user's first role
$role = auth()->user()->getRole();
// Get all user's roles
$roles = auth()->user()->roles;// Assign single role
$user->assignRole('admin');
// Assign multiple roles
$user->assignRole(['admin', 'editor']);
// Assign with specific guard
$user->assignRole('admin', 'api');// Check if user has permission
if (auth()->user()->hasPermission('users', 'create')) {
// User can create users
}
// Check with specific guard
if (auth()->user()->hasPermission('posts', 'delete', 'api')) {
// User can delete posts via API
}
// Get all user permissions
$permissions = auth()->user()->getAllPermissions();Besides artisan commands, you can also check relationships in your code:
use App\Models\User;
use Kiurd\RolePermissions\Models\Role;
use Kiurd\RolePermissions\Models\Module;
// Find which users have a specific role
$adminRole = Role::where('name', 'admin')->first();
$adminUsers = User::whereHas('roles', function($q) use ($adminRole) {
$q->where('id', $adminRole->id);
})->get();
// Find which roles have permission for a specific module
$userModule = Module::where('name', 'users')->first();
$rolesWithAccess = Role::whereHas('permissions', function($q) use ($userModule) {
$q->where('module_id', $userModule->id);
})->with(['permissions' => function($q) use ($userModule) {
$q->where('module_id', $userModule->id)->with('action');
}])->get();
// Get all permissions for a specific module
$userModule = Module::where('name', 'users')->first();
$permissions = $userModule->permissions()->with('action')->get();
// Get all users with a specific permission
$permission = Permission::whereHas('module', function($q) {
$q->where('name', 'users');
})->whereHas('action', function($q) {
$q->where('name', 'delete');
})->first();
$usersWithPermission = User::whereHas('roles.permissions', function($q) use ($permission) {
$q->where('permissions.id', $permission->id);
})->get();
// Check if a role has access to a specific module-action combination
$role = Role::where('name', 'editor')->first();
$hasAccess = $role->permissions()
->whereHas('module', function($q) {
$q->where('name', 'posts');
})
->whereHas('action', function($q) {
$q->where('name', 'create');
})
->exists();use Kiurd\RolePermissions\Helpers\PermissionHelper;
// Create a single permission
$permission = PermissionHelper::createPermission('users', 'create');
// Create multiple permissions
$permissions = PermissionHelper::createPermissions([
['module' => 'users', 'action' => 'create'],
['module' => 'users', 'action' => 'update'],
['module' => 'posts', 'action' => 'delete'],
]);
// Create full CRUD permissions for a module
$permissions = PermissionHelper::createCrudPermissions('products');
// Creates: products.create, products.read, products.update, products.delete, products.list
// Assign permissions to a role
PermissionHelper::assignPermissionsToRole('admin', [
['module' => 'users', 'action' => 'create'],
['module' => 'users', 'action' => 'delete'],
]);
// Check if permission exists
if (PermissionHelper::permissionExists('users', 'create')) {
// Permission exists
}
// Get all permissions for a module
$userPermissions = PermissionHelper::getModulePermissions('users');
// Delete a permission
PermissionHelper::deletePermission('users', 'create');use Kiurd\RolePermissions\Models\Role;
use Kiurd\RolePermissions\Models\Module;
use Kiurd\RolePermissions\Models\Action;
use Kiurd\RolePermissions\Models\Permission;
// Create a module
$module = Module::create([
'name' => 'products',
'guard_name' => 'web',
'description' => 'Product management'
]);
// Create an action
$action = Action::create([
'name' => 'create',
'guard_name' => 'web',
'description' => 'Create operation'
]);
// Create a permission (module + action)
$permission = Permission::create([
'module_id' => $module->id,
'action_id' => $action->id,
'guard_name' => 'web'
]);
// Create a role
$role = Role::create([
'name' => 'product-manager',
'guard_name' => 'web',
'description' => 'Manages products'
]);
// Assign permission to role
$role->givePermissionTo($permission);
// Remove permission from role
$role->awayPermissionTo($permission);
// Sync permissions (replaces all existing)
$role->syncPermissions([$permission1, $permission2]);
// Assign role to user
$user->assignRole('product-manager');Edit config/role_permissions.php to customize:
return [
// Enable auto-creation of permissions
'auto_create_permissions' => env('AUTO_CREATE_PERMISSIONS', false),
// Controller paths to scan
'controller_paths' => [
app_path('Http/Controllers'),
],
// Controllers to exclude from scanning
'excluded_controllers' => [
'App\Http\Controllers\Controller',
],
// Customize method to action mapping
'method_action_map' => [
'index' => 'list',
'show' => 'read',
'store' => 'create',
// ... add your custom mappings
],
];# Sync permissions from your controllers
php artisan permissions:sync --preview
php artisan permissions:sync
# Create roles
php artisan role:create admin
php artisan role:create editor
php artisan role:create viewer# Give admin full access
php artisan role:assign-permission admin users create
php artisan role:assign-permission admin users read
php artisan role:assign-permission admin users update
php artisan role:assign-permission admin users delete
# Give editor limited access
php artisan role:assign-permission editor users read
php artisan role:assign-permission editor users update// In your application code
$adminUser = User::find(1);
$adminUser->assignRole('admin');
$editorUser = User::find(2);
$editorUser->assignRole('editor');// Use auto-discovery middleware
Route::middleware(['auth', 'permission.auto'])->group(function () {
Route::resource('users', UserController::class);
Route::resource('posts', PostController::class);
Route::resource('products', ProductController::class);
});The package creates the following tables:
roles- Stores user rolesmodules- Stores resource modules (users, posts, etc.)actions- Stores actions (create, read, update, delete, etc.)permissions- Junction of modules and actionsrole_permissions- Assigns permissions to rolesuser_roles- Assigns roles to users
The package supports multiple authentication guards:
// Assign role with specific guard
$user->assignRole('admin', 'api');
// Check permission with guard
$user->hasPermission('users', 'create', 'api');
// Sync permissions with guard
php artisan permissions:sync --guard=api- Run sync after adding new controllers: Always sync permissions after creating new controllers or methods
- Use preview first: Use
--previewflag to see what will be synced before actually syncing - Enable auto-create in development: Set
AUTO_CREATE_PERMISSIONS=truein development for rapid prototyping - Disable auto-create in production: Keep it
falsein production for security and performance - Use auto-discovery middleware: Use
permission.automiddleware for automatic permission checking - Create meaningful module names: Structure your controllers with clear, meaningful names
- Make sure you've added the
HasRolesAndPermissionstrait to your User model - Run
php artisan permissions:syncto sync permissions - Verify user has the correct role assigned
- Check that the role has the required permissions
- Ensure
AUTO_CREATE_PERMISSIONS=truein your.env - Verify you're using the
permission.automiddleware - Check file permissions on your database
MIT License
Contributions are welcome! Please submit pull requests or open issues on GitHub.