itsmejoshua/novaspatiepermissions
A Laravel Nova tool for managing Spatie permissions straight from your admin panel. Browse, assign, and revoke roles and permissions for users through a clean Nova interface, making access control simple without custom code.
Minimal path from zero to a working permissions UI in Nova:
Install the underlying permission package first. This tool is a thin Nova layer over spatie/laravel-permission, so the real prerequisites are that package, its migrations, and its config:
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
Add the HasRoles trait to your User model before touching the Nova tool — the tool manages roles, but your app still has to use them.
Install the Nova tool:
composer require itsmejoshua/novaspatiepermissions
Register the tool in app/Providers/NovaServiceProvider.php inside tools(). The class name follows the vendor/package convention (Itsmejoshua\Novaspatiepermissions\Novaspatiepermissions), but confirm the exact FQCN against the repo README before relying on it:
public function tools()
{
return [
new \Itsmejoshua\Novaspatiepermissions\Novaspatiepermissions(),
];
}
Clear caches and reload Nova. php artisan nova:publish if the tool ships assets, then php artisan permission:cache-reset and a hard browser refresh. The tool appears as a sidebar entry for users who pass its authorization gate.
Where to look first: the package's src/ directory is small — start with the Tool class (for its canSee/canRun authorization logic and any cards()/resources() it registers) and its routes.php/Controllers. Because this is a low-adoption package (0 dependents, no stars to speak of), reading the source is faster and more trustworthy than reading docs.
First real use case: log in as a Nova super-admin, create a handful of permissions (view reports, edit invoices), group them into a Manager role, then attach that role to a user — all without touching tinker or seeders. From there, enforce it the normal Spatie way with @can, Gate, or policy checks in your app.
Treat the Nova tool as an admin console, not a source of truth. Seed your baseline roles/permissions in code (RoleSeeder, PermissionSeeder) so fresh environments are reproducible, and let the Nova UI handle the day-to-day churn of assigning roles to users. Without seeders, a migrate:fresh wipes your permission matrix.
Pair it with a guarded super-admin bypass. Nova itself is often the one place you don't want permission checks to lock you out. A Gate::before in AuthServiceProvider keeps the tool usable even if you accidentally strip a role:
Gate::before(function ($user, $ability) {
return $user->hasRole('super-admin') ? true : null;
});
Use Nova's own authorization for the tool entry point. Most Nova permission tools expose a canSee() that checks a specific permission or role. If you need finer control (e.g., only admin sees the tool), override it or gate the tool behind a policy rather than editing vendor code.
Multi-guard projects need explicit guard_names. If you run separate web and admin guards, every role/permission you create must carry the right guard, or hasPermissionTo() silently fails. Set guard_name explicitly in seeders and in the tool's forms.
Deleting roles and permissions is destructive and cascading. Spatie's pivot tables (role_has_permissions, model_has_roles, model_has_permissions) cascade on delete. Have the tool's users understand that deleting a role detaches it from every user instantly. For auditability, prefer disabling via a is_active flag on a custom Role model over deleting.
If you use Spatie's teams feature, the Nova tool typically has no concept of a "current team." You'll likely need to scope the tool's queries yourself or accept that it manages a flat, global matrix. Plan for a custom implementation if per-team management is required.
src/ for Nova version constraints (composer.json require of laravel/nova), check the last commit date, and pin the version in composer.lock. Treat any upgrade of Nova or spatie/laravel-permission as a potential break.public/vendor/itsmejoshua/novaspatiepermissions/ assets before assuming a backend bug.app(PermissionRegistrar::class)->forgetCachedPermissions(). Add a model observer on Role/Permission (or a saved/deleted listener) that flushes the cache. In production with multiple servers, ensure the cache store is shared (Redis) or you'll get inconsistent behavior per node.guard_name = 'web' cannot be assigned to a user whose roles use guard_name = 'api'. Debug with $user->getAllPermissions() and check the guard_name column directly.canSee()/policy — a registered tool that returns true unconditionally exposes your entire role matrix to every Nova user.vendor/. Anything inside vendor/ dies on the next composer update.php artisan route:list | grep nova (is the tool's route registered?), php artisan nova:install / re-publish assets (blank UI?), php artisan permission:cache-reset (stale data?), and php artisan tinker to verify Role::with('permissions')->get() returns what the UI claims.Role/Permission classes implementing Spatie\Permission\Contracts\Role) rather than via the tool itself. Configure those in config/permission.php — the Nova tool will generally respect whichever models the config points at, since it queries through the contract.How can I help you explore Laravel packages today?