Shinobi brings a simple and light-weight role-based permissions system to Laravel's built in Auth system.

ACL (Access Control List)

  • Every user can have zero or more permissions.
  • Every user can have zero or more roles.
  • Every role can have zero or more permissions.
  • Every role can have one of two special flags, all-access and no-access


Simply install the package through Composer. From here the package will automatically register its service provider and Shinobi facade.

composer require caffeinated/shinobi

We will document both versions 3.4 and 4.0. Both versions support Laravel 5.8. If you are currently on the 3.x release, please take this time to upgrade to the latest version ✌️


Shinobi provides middleware that you may assign to specific routes in your application. To register, simply append the following middleware to your app/Http/Kernel.php file under the $routeMiddleware property.

Check If User Has A Given Role

'has.role' => \Caffeinated\Shinobi\Middleware\UserHasRole::class,

Check If User Has A Given Permission

This is available in Shinobi 3.4. 4.0 does not include this as it hooks in to Laravel's gate system. If using Laravel 5.8 and Shinobi 4.0, simply use Laravel's can middleware to check permissions.

'has.permission' => \Caffeinated\Shinobi\Middleware\UserHasPermission::class,


Publish the provided migration files with the vendor:publish Artisan command.

php artisan vendor:publish --provider="Caffeinated\Shinobi\ShinobiServiceProvider"



Add the HasRolesAndPermissions trait to your User model.

use Illuminate\Foundation\Auth\User as Authenticatable;
use Caffeinated\Shinobi\Concerns\HasRolesAndPermissions;

class User extends Authenticatable
    use HasRolesAndPermissions;



Returns assigned roles for the given user.

$roles = auth()->user()->roles;


Checks if the given user has the specified role.

$isEditor = auth()->user()->hasRole('editor');


Assign the given role(s) to the user, by their slug.

auth()->user()->assignRoles('editor', 'vip');


Remove the given role(s) from the user, by their slug.



Sync the given role(s) for the user, by their slug. Any roles not provided will be removed from the user.



Returns assigned permissions for the given user (or role).

$permissions = auth()->user()->permissions;


Checks if the given user (or role) has the specified permission.

$isEditor = auth()->user()->hasPermissionTo('edit.pages');


The can method provided by Laravel may also be used. Behind the scenes, the gate policies Shinobi registers runs permissions through the hasPermissionTo method detailed above ✌️


Give the user (or role) specific permission(s).

auth()->user()->givePermissionTo('edit.pages', 'create.pages', 'delete.pages');


Revoke the given permission(s) from the user (or role).



Sync the given permission(s) against the user (or role). Any permissions not specified will be revoked.

auth()->user()->syncPermissions('edit.users', 'create.users', 'delete.users', 'view.users');


Add the ShinobiTrait trait to your User model.

use Caffeinated\Shinobi\Traits\ShinobiTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
    use ShinobiTrait;


Roles vs. Permissions

It's better for your application in the long run to simply check against permissions rather than specific roles. Roles are interchangeable and dynamic, having the ability to be assigned fine-grained permissions.

So instead of checking if a user has an admin role, check for a access.admin permission. In the future you may want to add Editors or Moderators that will need access to your admin section. If you hard coded the role in your code, you'd have to backtrack every instance where it checks for an admin role and add in conditionals for editor and moderator. Much easier to simply assign the access.admin permission to your Editor and Moderator roles and be done ✌️

Last Updated: 5/21/2019, 6:03:24 PM