Sure. You can either split your roles into smaller groups of permissions and give multiple roles to a usee, or simply give direct permissions to a user
https://docs.spatie.be/laravel-permission/v3/basic-usage/direct-permissions/
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Is it possible to have a user that has some permission of the role but not all of them?
For example: A user has the Admin role, the Admin role has permissions: A, B and C The user has the Admin role, but I want the user to have only A and B permissions.
Can this be done with Spatie Permissions?
Well, the solution seems simple enough, accourding to their documentaion. But there's a catch: you need to re-think your strategy regarding roles and permissions because there is no way to revoke a permission granted through a role (because it makes little sense).
You should instead assign to roles ONLY the permissions that everybody in that role will have. If you want certain people with a role to have extra permissions, then you add them directly, or via a new role.
Given this world:
$adminRole = Role::create(['name' => 'Admin']);
// all the permissions in your system
$read = Permission::create(['name' => 'read']); // id 1
$create = Permission::create(['name' => 'create']); // id 2
$editOwn = Permission::create(['name' => 'edit own']); // id 3
$editFromOthers = Permission::create(['name' => 'edit from others']); // id 4
$deleteOwn = Permission::create(['name' => 'delete own']); // id 5
$deleteFromOthers = Permission::create(['name' => 'delete from others']); // id 6
This, as far as I can tell, is what you do and it doesn't work:
// all admins have all permissions
$permissions = Permissions::all();
$adminRole->syncPermissions($permissions);
// a user with a role should not have some admin permissions
$admin = User::first()->assignRole($adminRole);
$admin->revokePermissionTo('delete from others');
// this returns true because the permission is not directly given to the user, but it is inherited from the role
$admin->hasPermissionTo('delete from others'); // true :(
What I would suggest you to do, is something like:
// your standard admin role with permissions that are granted to everybody in the role
$adminPermissions = Permission::find([1, 2, 3, 5]); // deal with their own stuff
$adminRole->syncPermissions($adminPermissions);
// your standard admins
$oneAdmin = User::find(1)->assignRole($adminRole);
$anotherAdmin = User::find(2)->assignRole($adminRole);
$trustWorthyAdmin = User::find(10)->assignRole($adminRole);
// now, this person is special
$trustWorthyAdmin->givePermissionTo('edit from others');
$trustWorthyAdmin->givePermissionTo('delete from others');
// when trust-worthy-admin becomes not so much trust-worthy
$trustWorthyAdmin->revokePermissionTo('delete from others');
// this returns false, which is what you want
$trustWorthyAdmin->hasPermissionTo('delete from others'); // flase :D
In alternative, when more people are involved:
// your standard admin role with permissions that are granted to everybody in the role
$adminPermissions = Permission::find([1, 2, 3, 5]); // deal with their own stuff
$adminRole->syncPermissions($adminPermissions);
// your new powerfull super admin role
$superAdminPermissions = Permission::find([4, 6]);
$superAdminRole = Role::create(['name' => 'Super Admin']);
$adminRole->syncPermissions($permissions);
// standard admins
$oneAdmin = User::find(1)->assignRole($adminRole);
$anotherAdmin = User::find(2)->assignRole($adminRole);
// trust-worthy admins
$trustWorthyAdmins = User::find([8, 9, 10])->assignRole($adminRole);
$trustWorthyAdmins->assignRole($superAdminRole);
You should also have in mind their suggestion on dealing with roles and permissions:
It is generally best to code your app around permissions only. That way you can always use the native Laravel @can and can() directives everywhere in your app.
Hope this helps!
Please or to participate in this conversation.