mphpmaster/laravel-nova-blueprint-permission
Blueprint-style permission management for Laravel Nova: define roles and permissions declaratively, attach them to Nova resources, and keep access control consistent from one centralized interface. Built for teams that want readable, version-friendly authorization setup.
This package sits at the intersection of two things: Laravel Nova (the admin UI) and Blueprint (laravel-shift/blueprint, the YAML-driven code generator). Before writing any code, spend five minutes confirming which mode you are in — the package description reads like a runtime Nova tool ("manage roles and permissions directly from Nova"), but the published assessment and package name point to a build-time Blueprint generator that emits Nova resources and permission wiring, typically against spatie/laravel-permission. Inspect composer.json and the service provider to settle this; it changes everything below.
If it is a build-time generator (most likely):
composer require mphpmaster/laravel-nova-blueprint-permission --dev
composer require laravel-shift/blueprint --dev
Publish stubs and config so you can customise output rather than vendor-edit:
php artisan vendor:publish --provider="mPhpMaster\LaravelNovaBlueprintPermission\ServiceProvider"
Look first at:
drafts/ at the project root — this is the input contract. Blueprint reads from here, not resources/. Most "nothing generated" reports are a wrong draft location.config/ — generator toggles, guard settings, permission naming.app/Nova/ after one build — the actual artefact you care about.First use case: take an existing model in a draft, run:
php artisan blueprint:build --only=Post -v
Confirm a Nova resource lands in app/Nova/Post.php, a policy alongside it, and that the policy methods reference your permission names. That single loop — draft → build → inspect → adjust stub — is the whole day-to-day workflow.
If it turns out to be a runtime Nova tool instead: register it in NovaServiceProvider::tools() (or via the package provider), run php artisan nova:tool if it ships a tool scaffold, and validate that the roles/permissions tables from Spatie exist and are migrated before opening the UI.
Draft-as-source-of-truth. Keep Blueprint YAML in version control and regenerate. Generate commits should show clean, reviewable diffs of Resources, Policies and migrations. If a diff is noisy, your stubs are the place to fix it, not the output.
Generate the policy, then seed from it. Don't hand-type permission strings in seeders. Let the generator emit the policy, then derive permission names from the policy methods so UI gates and seeders can never drift:
// database/seeders/PermissionSeeder.php
foreach ([Post::class, Comment::class] as $model) {
foreach (['viewAny', 'view', 'create', 'update', 'delete'] as $action) {
Permission::firstOrCreate(['name' => "{$action} " . class_basename($model)]);
}
}
Assign to roles via Spatie, and attach the same names in the generated Nova resource's authorizable()/canSee() checks.
Iterate one model at a time, build fully before PR.
php artisan blueprint:build --only=Post # tight loop while tuning
php artisan blueprint:build # full build catches relations/policies
git diff # review before commit
Customise naming in one place. Publish stubs and pick a convention (viewAny Post vs index Post) inside the stub. The generator then applies it consistently across every resource — this is the single highest-leverage customisation you will make.
Keep hand edits outside generated files. Generated Nova resources and policies are not merge-aware. Put bespoke fields, actions and gate logic in traits or custom resource classes that the stub references, so regeneration is safe.
CI drift check.
- run: php artisan blueprint:build
- run: git diff --exit-code
This enforces that drafts are the only place Nova resources are authored, and catches "someone edited the generated file directly" before it reaches main.
Guard alignment. Check that generated policies use the same guard your app authenticates against (config/auth.php → guards, and config/permission.php → defaults.guard). If your users authenticate on api but generated policies check web, permission resolution silently fails.
Cache hygiene. If wiring to Spatie, remember permission results are cached. After seeding or changing roles in local/dev:
php artisan permission:cache-reset
^2.0 if you need runway; assume ^3.0 may change stubs, config keys, or dependency constraints (Laravel/PHP/Nova support).blueprint:build destroys hand edits to app/Nova/* and generated policies. Never edit generated files as a habit; extend via traits/custom classes referenced by the stub.require-dev. Shipping them in require pushes a code-generation dependency into production with no runtime value.web default guard silently break generated policy checks. Cross-check config/permission.php against auth.guards after publishing.drafts/ at project root. Not resources/, not app/drafts/. Check this first when output is missing.-v. php artisan blueprint:build -v prints emitted file paths; it resolves most "it didn't generate" reports in one run.vendor/ vanish on the next composer update.How can I help you explore Laravel packages today?