yadahan/nova-bouncer
Provides Laravel Nova resources for Bouncer, the roles and permissions package. Manage roles, abilities, and entity assignments directly from Nova with a clean, searchable interface, letting admins grant or revoke access without touching code.
Architecture fit. This is a Nova presentation layer that reads and writes Bouncer's role/ability tables — not an authorization engine, and it must never be scoped as one. The value is confined to the narrow intersection of two deliberate stack choices: a licensed Laravel Nova install and Bouncer wired into models via the HasRolesAndAbilities trait. If the team is on spatie/laravel-permission (the dominant choice) there is no adapter and no path — stop evaluating. If there is no Nova license, the prerequisite cost dominates and the package delivers nothing. Treat those two prerequisites as hard gates before any estimate is produced.
Integration feasibility. Low technical effort, high prerequisite friction. composer require, publish provider assets, register the tool in NovaServiceProvider::tools(), gate it with canSee. The source is small enough to read in an afternoon, which matters because the repo publishes no compatibility matrix — composer.json constraints in the package are the real matrix. Frontend assets under resources/js/ are where Nova major upgrades break third-party tools, and that is the only part the package truly owns.
Technical risk. Concentrated and predictable:
toOwn), entity-scoped abilities, and multiple guards. A generic CRUD UI is unlikely to expose all of it. Anything the UI cannot express becomes out-of-band database work, which quietly defeats the delegation rationale.edit-users on a Friday afternoon" is unanswerable without observers you write yourself.Bouncer::refresh() / refreshFor($user) or admins will "fix" a permission and see nothing change.Key questions for the spike.
Bouncer::scope() or globally — a UI showing global roles to a tenant admin is a cross-tenant privilege escalation.Stack fit. Internal admin panels, SaaS back-offices where account owners assign roles inside their tenant, agency-delivered client admin UIs, and Nova-based internal tooling. Poor fit for API-only products, spatie shops, or anything needing vendor support.
Migration path — seeder-first, UI-second. The UI is an operational surface, not a schema tool. Structural roles and abilities belong in idempotent seeders so staging refreshes and migrate:fresh reproduce production authorization state. Admins use the UI for the volatile part — who holds a role. Keep what a role means in code review. This is also the incremental adoption story: Bouncer's API can be introduced without a data migration, replacing hand-rolled is_admin flags over time.
Compatibility. Pin the package in composer.json to an exact tag or 1.x. Spike in staging on the exact Nova/Laravel/PHP combination intended for production. Set an explicit review trigger: if a Nova upgrade breaks it, or upstream goes six months without a release, we fork. Budget that outcome now rather than funding it out of an incident.
Sequencing.
spatie).composer.json, src/, routes/, and resources/js/ — confirm the tool's own routes are authorized and what save does.resource.action, e.g. posts.publish) in an enum shared by seeders and policies.canSee — never ship the menu entry ungated, and never use a global Gate::before that returns true unconditionally or false instead of null.Gate::allows() so the tool is never on the request path.Rollback story. Removal is clean: drop it from tools() and composer remove; Bouncer's tables and data survive untouched. Write that down before rollout so nobody reaches for migrate:fresh.
Maintenance. Assume fork ownership from day one. Pin the version, run a staging spike on every Nova major, and hold a standing review trigger. Keep changes to the tool itself in a fork with our own tests rather than patching vendor code in place.
Support. MIT, no SLA, single maintainer, no dependents, no shared upgrade path. Treat it as auditable sample code we may inherit, not a supported product. The buy case rests entirely on 2–5 days of saved CRUD work — an acceptable trade, but only if the fork outcome is pre-funded.
Scaling. Large role/ability or entity datasets degrade the UI; confirm pagination, search, and eager loading against production-scale data in the spike. Bulk changes belong in artisan commands, not a browser. Cache staleness does not necessarily clear across already-warm queue workers or Octane processes — restart workers on deploy, or invalidate inside the job boundary and accept staleness by design.
Failure modes and their blast radius.
roles, abilities, and pivots before bulk edits.Ramp-up. Ops leads, support managers, and account owners can drive the screen with minimal training — that is the product win: converting a steady stream of permission-change tickets into a shipped admin screen. Engineer ramp-up is the cost: roughly an afternoon reading source plus spike time. Debugging follows a fixed order that separates a UI bug from an authorization bug in about two minutes: (1) tool registered and not filtered by canSee, (2) assets built/published for the Nova version, (3) write landed in roles/abilities/pivots, (4) cache refreshed, (5) the policy returns the expected result.
What this should and should not drive. It accelerates build-vs-buy for RBAC back-office screens, pulls "let ops manage roles themselves" forward cheaply, and supports migrating off ad-hoc is_admin flags. It must not drive the authorization model itself, tenancy strategy, or audit/compliance posture — those are Bouncer and application-code decisions, and audit trails and approval chains are out of scope entirely.
How can I help you explore Laravel packages today?