Skip to main content

Installation Steps

Follow these steps to install and configure Laravel Permission in your application.
1

Install the Package

Install the package via Composer:
composer require spatie/laravel-permission
The package will automatically register its service provider.
Make sure you meet the prerequisites before installing.
2

Publish the Configuration

Publish the configuration file and migrations:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
This will create:
  • config/permission.php - Configuration file
  • Database migration files in database/migrations/
You can customize table names, models, and other settings in the config file.
3

Run the Migrations

Run the migrations to create the necessary database tables:
php artisan migrate
This creates the following tables:
  • permissions - Stores all permissions
  • roles - Stores all roles
  • model_has_permissions - Pivot table for direct user permissions
  • model_has_roles - Pivot table for user roles
  • role_has_permissions - Pivot table for role permissions
4

Add the Trait to Your User Model

Add the HasRoles trait to your User model:
app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ... rest of your User model
}
The HasRoles trait also includes the HasPermissions trait, giving you access to all permission methods.
5

Clear Cache

Clear your application cache to ensure the package is properly loaded:
php artisan optimize:clear
Or clear individual caches:
php artisan config:clear
php artisan cache:clear

Verify Installation

You can verify the installation by creating a permission:
php artisan tinker

>>> use Spatie\Permission\Models\Permission;
>>> Permission::create(['name' => 'edit articles']);
>>> Permission::all();

Database Schema

Here’s an overview of the tables created by the migrations:

permissions

ColumnTypeDescription
idbigintPrimary key
namevarcharPermission name (e.g., ‘edit articles’)
guard_namevarcharGuard name (e.g., ‘web’, ‘api’)
created_attimestampCreation timestamp
updated_attimestampUpdate timestamp

roles

ColumnTypeDescription
idbigintPrimary key
namevarcharRole name (e.g., ‘writer’, ‘admin’)
guard_namevarcharGuard name (e.g., ‘web’, ‘api’)
created_attimestampCreation timestamp
updated_attimestampUpdate timestamp

model_has_permissions

ColumnTypeDescription
permission_idbigintForeign key to permissions
model_typevarcharModel class name
model_idbigintModel ID

model_has_roles

ColumnTypeDescription
role_idbigintForeign key to roles
model_typevarcharModel class name
model_idbigintModel ID

role_has_permissions

ColumnTypeDescription
permission_idbigintForeign key to permissions
role_idbigintForeign key to roles

Configuration

The config/permission.php file contains all configuration options. Here are some key settings:
Customize which Eloquent models are used for permissions and roles:
config/permission.php
'models' => [
    'permission' => Spatie\Permission\Models\Permission::class,
    'role' => Spatie\Permission\Models\Role::class,
],
You can extend these models with your own custom models.
Customize the database table names:
config/permission.php
'table_names' => [
    'roles' => 'roles',
    'permissions' => 'permissions',
    'model_has_permissions' => 'model_has_permissions',
    'model_has_roles' => 'model_has_roles',
    'role_has_permissions' => 'role_has_permissions',
],
Configure permission caching:
config/permission.php
'cache' => [
    'expiration_time' => \DateInterval::createFromDateString('24 hours'),
    'key' => 'spatie.permission.cache',
    'store' => 'default',
],
Caching significantly improves performance by reducing database queries.
Enable multi-tenancy support:
config/permission.php
'teams' => false, // Set to true to enable teams
'team_foreign_key' => 'team_id',
You must set teams to true before running migrations if you want team support.
Enable wildcard permission matching:
config/permission.php
'enable_wildcard_permission' => false,
When enabled, you can use patterns like articles.* to match multiple permissions.

Seed Sample Data

It’s a good practice to seed your database with initial roles and permissions:
database/seeders/PermissionSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class PermissionSeeder extends Seeder
{
    public function run(): void
    {
        // Reset cached roles and permissions
        app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();

        // Create permissions
        Permission::create(['name' => 'edit articles']);
        Permission::create(['name' => 'delete articles']);
        Permission::create(['name' => 'publish articles']);
        Permission::create(['name' => 'unpublish articles']);

        // Create roles and assign permissions
        $role = Role::create(['name' => 'writer']);
        $role->givePermissionTo(['edit articles', 'delete articles']);

        $role = Role::create(['name' => 'editor']);
        $role->givePermissionTo(['edit articles', 'delete articles', 'publish articles', 'unpublish articles']);

        $role = Role::create(['name' => 'admin']);
        $role->givePermissionTo(Permission::all());
    }
}
Run the seeder:
php artisan db:seed --class=PermissionSeeder

Troubleshooting

Make sure you’ve run the migrations:
php artisan migrate
If you’ve published the migrations but they’re not running, check that the migration files exist in database/migrations/.
Clear your autoload cache:
composer dump-autoload
php artisan optimize:clear
Clear the permission cache:
php artisan cache:forget spatie.permission.cache
Or in code:
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
If your User model uses UUIDs, update the column configuration:
config/permission.php
'column_names' => [
    'model_morph_key' => 'model_uuid',
],

Next Steps

Basic Concepts

Learn about roles, permissions, and guards

Using Permissions

Start using roles and permissions in your app

Build docs developers (and LLMs) love