laravel-permission

SkillAI & models

Use when implementing RBAC, role-based access control, or user authorization with Spatie Laravel Permission.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the laravel-permission skill

What this skill tells your AI

The instructions your AI receives, as published by fusengine/agents in plugins/laravel-expert/skills/laravel-permission/SKILL.md and read by ahel’s review.

Laravel Permission (Spatie)

Agent Workflow (MANDATORY)

Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:

  1. fuse-ai-pilot:explore-codebase - Check existing auth patterns
  2. fuse-ai-pilot:research-expert - Verify Spatie Permission docs via Context7
  3. mcp__context7__query-docs - Check Laravel authorization patterns

After implementation, run fuse-ai-pilot:sniper for validation.


Overview

Spatie Laravel Permission provides complete role-based access control (RBAC) for Laravel applications.

ComponentPurpose
RoleGroup of permissions (admin, writer)
PermissionSingle ability (edit articles)
MiddlewareRoute protection
Blade DirectivesUI authorization
TeamsMulti-tenant scoping
WildcardsHierarchical permissions
Super AdminBypass all checks
EventsAudit logging (v6.15.0+)
Query ScopesFilter users by role/permission
API SupportSanctum/Passport integration
PoliciesResource-based authorization

Critical Rules

  1. Seed roles/permissions in DatabaseSeeder
  2. Cache reset after changes: php artisan permission:cache-reset
  3. Use kebab-case for naming: edit-articles
  4. Never hardcode role checks in controllers - use middleware
  5. Set team context early in request for multi-tenant apps
  6. Specify guard for API - permission:edit,api
  7. Clear cache in tests - Reset in setUp()/beforeEach()

Reference Guide

Core Concepts

TopicReferenceWhen to consult
Setupspatie-permission.mdInstallation, model setup, core methods
Middlewaremiddleware.mdRoute protection patterns
Bladeblade-directives.mdUI authorization directives
Direct vs Roledirect-permissions.mdPermission inheritance

Advanced Features

TopicReferenceWhen to consult
Teamsteams.mdMulti-tenant permissions
Wildcardswildcard-permissions.mdHierarchical patterns
Super Adminsuper-admin.mdBypass all permissions
Custom Modelscustom-models.mdUUID, extending models

Integration

TopicReferenceWhen to consult
API Usageapi-usage.mdSanctum, guards, JSON responses
Policiespolicies.mdLaravel Policy integration
Query Scopesquery-scopes.mdUser::role(), User::permission()
Eventsevents.mdAudit logging, notifications

Operations & Quality

TopicReferenceWhen to consult
Cachecache.mdPerformance, debugging
CLIartisan-commands.mdArtisan commands
Testingtesting.mdTests, factories, setup
Performanceperformance.mdOptimization, N+1, caching

Templates (Code Examples)

Setup & Seeding
TemplatePurpose
UserModel.php.mdUser model with HasRoles trait
RoleSeeder.php.mdBasic role seeding
PermissionSeeder.php.mdPermission creation seeder
WildcardSeeder.php.mdHierarchical permissions
Routes & Middleware
TemplatePurpose
routes-example.mdProtected routes examples
ControllerMiddleware.php.mdMiddleware in controllers
BladeExamples.blade.mdBlade directive examples
Teams & Multi-Tenant
TemplatePurpose
TeamMiddleware.php.mdMulti-tenant middleware
TeamSeeder.php.mdTeam-scoped roles seeder
TeamModel.php.mdTeam model with boot
Super Admin & Cache
TemplatePurpose
SuperAdminSetup.php.mdGate::before bypass
CacheConfig.php.mdCache configuration
DeployScript.sh.mdCI/CD cache management
API Integration
TemplatePurpose
ApiPermissionSetup.php.mdAPI guard + Sanctum
ApiExceptionHandler.php.mdJSON error responses
ApiUserResource.php.mdUser resource with permissions
Policies & Events
TemplatePurpose
PostPolicy.php.mdPolicy with Spatie integration
PermissionEventListener.php.mdAudit event listeners
UserQueryExamples.php.mdQuery scope examples
PermissionAudit.php.mdAudit service
Testing
TemplatePurpose
PermissionTest.php.mdPest & PHPUnit tests
UserFactory.php.mdFactory with permission states
Custom Models
TemplatePurpose
CustomRole.php.mdExtended Role model
CustomPermission.php.mdExtended Permission model
UUIDMigration.php.mdUUID tables migration
SetupPermissions.php.mdCustom artisan command

Quick Reference

Assign Role

$user->assignRole('admin');

Check Permission

$user->can('edit articles');

Middleware (Web)

Route::middleware(['role:admin'])->group(fn () => ...);

Middleware (API)

Route::middleware(['auth:sanctum', 'permission:edit,api'])->group(fn () => ...);

Blade

@role('admin') ... @endrole
@can('edit articles') ... @endcan

Query Scopes

User::role('admin')->get();
User::permission('edit articles')->get();

Teams

setPermissionsTeamId($team->id);

Wildcards

$role->givePermissionTo('articles.*');

Super Admin

Gate::before(fn ($user, $ability) =>
    $user->hasRole('Super-Admin') ? true : null
);

Testing

beforeEach(fn () => app(PermissionRegistrar::class)->forgetCachedPermissions());

Feature Matrix

FeatureStatusReference
Basic RBACspatie-permission.md
Middlewaremiddleware.md
Blade Directivesblade-directives.md
Multi-Guard (web/api)middleware.md, api-usage.md
Teams (Multi-Tenant)teams.md
Wildcard Permissionswildcard-permissions.md
Super Adminsuper-admin.md
Cache Managementcache.md
Direct vs Role Permsdirect-permissions.md
Artisan Commandsartisan-commands.md
UUID Supportcustom-models.md
Custom Modelscustom-models.md
Events (v6.15.0+)events.md
Query Scopesquery-scopes.md
Policy Integrationpolicies.md
API / Sanctumapi-usage.md
Testingtesting.md
Performanceperformance.md

Laravel 13 Notes

Spatie Permission 6.24 est compatible Laravel 13. Intégrations L13 :

  • Cache prefix hyphens : spatie.permission.cache devient spatie-permission-cache ; configurer permission.cache.key si rétro-compat requise
  • Attributes Controllers : combiner #[Authorize] (policy) et #[Middleware('role:admin')] (RBAC) — voir [[laravel-blade]]
  • PHP 8.3 : final readonly class pour Role/Permission DTOs custom
#[Middleware(['auth', 'role:admin|editor'])]
#[Authorize('update', Post::class)]
public function update(UpdatePostRequest $request, Post $post) { /* ... */ }

Best Practices

DO

  • Définir une seule source de vérité : Policy OU Permission (pas les deux pour la même action)
  • Utiliser permission:create-post (verb-noun) pour clarté
  • Activer teams uniquement si réel multi-tenant
  • Cacher les permissions par utilisateur (Cache::remember('user.permissions.'.$id, ...))
  • Super admin via Gate::before() (jamais via permission wildcard *)

DON'T

  • Stocker permissions en session (utiliser le cache Spatie)
  • Mixer hasRole() et hasPermissionTo() sans cohérence d'architecture
  • Hardcoder noms de rôles dans le code (utiliser enum RoleEnum)
  • Oublier de purger le cache après assignRole() en seeder
  • Donner * à un super admin (préférer Gate::before() ciblé)

Signals

GitHub stars
25
Forks
4
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
laravel-permission
Source
github.com/fusengine/agents