- What Laravel versions does spatie/laravel-permission support, and how do I check compatibility with my project?
- The latest version (v7+) requires Laravel 12+ and PHP 8.3+. Version 6 supports Laravel 9–11 and PHP 8.0–8.2. Check your Laravel version with `php artisan --version` and ensure your PHP version matches the package’s requirements. For legacy projects (Laravel 8/9), use v5, but note it’s unsupported.
- How do I assign permissions to users or roles, and can I use wildcards like `admin.*`?
- Use `givePermissionTo()` for direct assignments (e.g., `$user->givePermissionTo('edit articles')`) or assign roles with `assignRole()`. Wildcard permissions (e.g., `admin.*`) are supported but require careful design to avoid performance issues. Enable them via `Permission::create('admin.*')` and check with `$user->can('admin.create-post')`.
- Does this package work with Laravel’s policies and gates, or do I need to choose one?
- It works seamlessly with both. Permissions are registered as gates automatically, so you can use `$user->can('edit', Post::class)` or `$user->can('edit articles')`. Policies remain fully functional for model-specific logic, while permissions handle broader access control. The package bridges both systems.
- How do I secure routes with permissions, and is there built-in middleware?
- Use the included `RoleOrPermissionMiddleware` to protect routes. Add it to your `RouteMiddleware` array and apply it to routes like this: `Route::middleware(['role:admin'])->group(...)` or `Route::middleware(['permission:edit articles'])->group(...)`. For dynamic checks, use `authorize()` in controllers.
- What are the performance implications of caching permissions, and how do I disable it?
- Permissions are cached by default for speed, but this can cause stale data in high-concurrency environments (e.g., Octane). Disable caching by setting `'cache_permissions' => false` in the config. For large permission sets (>10K), consider denormalizing permissions or using a dedicated cache like Redis with tags.
- Can I use this package for multi-tenant SaaS apps, and how do I scope permissions to tenants?
- Yes, but you’ll need to implement tenant-specific logic manually. Use middleware to attach the tenant to the request, then scope queries (e.g., `Permission::where('tenant_id', $tenantId)`). The package doesn’t enforce tenancy out of the box, so combine it with packages like `stancl/tenancy` for full isolation.
- How do I audit permission changes (e.g., role assignments) using Laravel events?
- The package dispatches events like `RoleAssigned`, `PermissionRevoked`, and `UserSynced`. Listen to them in `EventServiceProvider` or use a package like `spatie/laravel-activitylog` to log changes. Example: `event(new RoleAssigned($user, $role));` triggers automatically when roles are assigned.
- What’s the upgrade path from v6 to v7, and are there breaking changes?
- Upgrade via Composer (`composer require spatie/laravel-permission:^7.0`), then run migrations. Key changes include renamed events (e.g., `RoleAssigned` → `RoleCreated`), stricter type hints, and Pest test suite updates. Backup your database first, as some event classes and config keys may differ. Check the [upgrade guide](https://spatie.be/docs/laravel-permission/upgrade) for details.
- Is there a way to sync permissions with an external system (e.g., LDAP or OAuth)?
- Yes, use the `syncPermissions()` method to update permissions programmatically. For external systems, listen to events (e.g., `PermissionCreated`) and sync data via queues or webhooks. Example: `Permission::syncPermissions($externalPermissionsArray)`. Combine with packages like `ldaprecord/ldap` for LDAP integration.
- How do I test permission logic in Laravel, especially with Pest or PHPUnit?
- Use Pest’s `actingAs()` helper to simulate logged-in users, then assert permissions with `$this->assertTrue($user->can('edit articles'))`. For complex scenarios, mock the `Gate` facade or use `Permission::fake()` to isolate tests. Example: `Permission::fake(['edit articles' => true]);`. The package includes Pest presets for quick setup.