api-security
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Build and work with Spatie Laravel Permission features, including roles, permissions, middleware, policies, teams, and Blade directives.
Claude Code
$ npx -y skills add spatie/laravel-permission --skill laravel-permission-development --agent claude-code
Codex
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a codex -y
Cursor
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a cursor -y
Gemini CLI
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a gemini-cli -y
GitHub Copilot
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a github-copilot -y
OpenCode
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a opencode -y
Windsurf
$ npx skills add spatie/laravel-permission --skill laravel-permission-development -a windsurf -y
name: laravel-permission-development description: Build and work with Spatie Laravel Permission features, including roles, permissions, middleware, policies, teams, and Blade directives.
Use this skill when working with authorization, roles, permissions, access control, middleware guards, or Blade permission directives using spatie/laravel-permission.
Add the `HasRoles` trait to your User model:
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
$role = Role::create(['name' => 'writer']);
$permission = Permission::create(['name' => 'edit articles']);
// findOrCreate is idempotent (safe for seeders)
$role = Role::findOrCreate('writer', 'web');
$permission = Permission::findOrCreate('edit articles', 'web');// Assign roles to users
$user->assignRole('writer');
$user->assignRole('writer', 'admin');
$user->assignRole(['writer', 'admin']);
$user->syncRoles(['writer', 'admin']); // replaces all
$user->removeRole('writer');
// Assign permissions to roles (preferred)
$role->givePermissionTo('edit articles');
$role->givePermissionTo(['edit articles', 'delete articles']);
$role->syncPermissions(['edit articles', 'delete articles']);
$role->revokePermissionTo('edit articles');
// Reverse assignment
$permission->assignRole('writer');
$permission->syncRoles(['writer', 'editor']);
$permission->removeRole('writer');// Permission checks (preferred - supports Super Admin via Gate)
$user->can('edit articles');
$user->canAny(['edit articles', 'delete articles']);
// Direct package methods (bypass Gate, no Super Admin support)
$user->hasPermissionTo('edit articles');
$user->hasAnyPermission(['edit articles', 'publish articles']);
$user->hasAllPermissions(['edit articles', 'publish articles']);
$user->hasDirectPermission('edit articles');
// Role checks
$user->hasRole('writer');
$user->hasAnyRole(['writer', 'editor']);
$user->hasAllRoles(['writer', 'editor']);
$user->hasExactRoles(['writer', 'editor']);
// Get assigned roles and permissions
$user->getRoleNames(); // Collection of role name strings
$user->getPermissionNames(); // Collection of permission name strings
$user->getDirectPermissions(); // Direct permissions only
$user->getPermissionsViaRoles(); // Inherited via roles
$user->getAllPermissions(); // Both direct and inherited$users = User::role('writer')->get();
$users = User::withoutRole('writer')->get();
$users = User::permission('edit articles')->get();
$users = User::withoutPermission('edit articles')->get();Register middleware aliases in `bootstrap/app.php`:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
})Use in routes (pipe `|` for OR logic):
Route::middleware(['permission:edit articles'])->group(function () { ... });
Route::middleware(['role:manager|writer'])->group(function () { ... });
Route::middleware(['role_or_permission:manager|edit articles'])->group(function () { ... });
// With specific guard
Route::middleware(['role:manager,api'])->group(function () { ... });For single permissions, Laravel's built-in `can` middleware also works:
Route::middleware(['can:edit articles'])->group(function () { ... });Prefer `@can` (permission-based) over `@role` (role-based):
@can('edit articles')
{{-- User can edit articles (supports Super Admin) --}}
@endcan
@canany(['edit articles', 'delete articles'])
{{-- User can do at least one --}}
@endcanany
@role('admin')
{{-- Only use for super-admin type checks --}}
@endrole
@hasanyrole('writer|admin')
{{-- Has writer or admin --}}
@endhasanyroleUse `Gate::before` in `AppServiceProvider::boot()`:
use Illuminate\Support\Facades\Gate;
public function boot(): void
{
Gate::before(function ($user, $ability) {
return $user->hasRole('Super Admin') ? true : null;
});
}This makes `$user->can()` and `@can` always return true for Super Admins. Must return `null` (not `false`) to allow normal checks for other users.
Use `$user->can()` inside policy methods to check permissions:
class PostPolicy
{
public function update(User $user, Post $post): bool
{
if ($user->can('edit all posts')) {
return true;
}
return $user->can('edit own posts') && $user->id === $post->user_id;
}
}enum RolesEnum: string
{
case WRITER = 'writer';
case EDITOR = 'editor';
}
enum PermissionsEnum: string
{
case EDIT_POSTS = 'edit posts';
case DELETE_POSTS = 'delete posts';
}
// Most methods accept enums directly
Permission::findOrCreate(PermissionsEnum::EDIT_POSTS, 'web');
$user->assignRole(RolesEnum::WRITER);
$user->hasRole(RolesEnum::WRITER);
$role->givePermissionTo(PermissionsEnum::EDIT_POSTS);
$user->hasPermissionTo(PermissionsEnum::EDIT_POSTS);Always flush the permission cache when seeding:
class RolesAndPermissionsSeeder extends Seeder
{Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…