jeremykenedy/laravel-roles
jeremykenedy/laravel-roles is a comprehensive Laravel package for managing user roles and permissions. It provides migrations, models, middleware, Blade directives, and an optional admin interface to create roles, assign permissions, and protect routes with ease.
What it is: jeremykenedy/laravel-roles — an in-process RBAC package for Laravel: roles, permissions, levels and inheritance, route middleware (role, permission, level), Blade directives, an admin GUI, and an optional JSON API.
Architecture fit: Config-driven, publishes config/migrations/views, builds on Eloquent models and middleware aliases. It fits a standard Laravel monolith that needs application-level RBAC without standing up a separate authorization service. It fits less well where requirements are multi-tenant per-tenant isolation, policy/ABAC-heavy rules, or a centralized decision point shared across services.
Integration feasibility: Composer install, then roles:install to publish config and select a CSS framework. The --css and --force flags make that reproducible in CI rather than an interactive prompt. The three self-contained view sets (Bootstrap 4 default, Bootstrap 5, Tailwind) reduce coupling to the host app's frontend, and the Tailwind set ships inline SVG so it pulls in no icon font. The new docs/ tree covering install through upgrade removes most of the integration tax that normally dominates adoption of a package like this.
Technical risk:
auth:api; rolesAPIAuthEnabled, rolesAPIMiddlewareEnabled and rolesAPIMiddleware (default role:admin) were inert. On upgrade, existing API consumers authenticating with a role not literally named admin will start receiving 403s. The documented escape hatch, ROLES_API_MIDDLEWARE_ENABLED=false, restores a state where any authenticated user can read every role, permission and user and create roles — that should be a ticketed, time-boxed exception, never the steady state.composer audit is clean. Every v12.x install carries the XSS.Key questions:
ROLES_API_ENABLED=true anywhere, and if so who calls the API and with what token? Does a role literally named admin exist, and is that the gate we actually want?config/roles.php, the views, or the migrations — and do we extend the package's models or call getPermissions() directly?Stack fit: A drop-in for Laravel apps already using Eloquent, Blade and route middleware. The three middleware, the Blade directives, and seeded roles/permissions map onto conventional application authorization. The GUI is opt-in and its view sets are self-contained, so it can be adopted or skipped without forcing a frontend build change.
Migration path (v12 → v13):
composer.json constraints, Laravel/PHP versions per app, config/roles.php overrides, and whether config, views and migrations are published or customized.rolesAPIAuthEnabled, rolesAPIMiddlewareEnabled and rolesAPIMiddleware. Decide deliberately whether role:admin is the correct gate before deploying, not after the first 403 report.composer audit, validate in staging, then roll forward environment by environment with the config diff reviewed each time.Compatibility: Treat the tested matrix (PHP 8.2–8.4, Laravel 12–13) as the supported matrix and everything else as best-effort. Laravel 11 is declared-but-untested and may not even resolve under default Composer policy — either move those apps to a supported Laravel or accept and document the risk explicitly.
Sequencing: Security triage first — establish whether we are exposed to the stored XSS and to the API authorization gap — then upgrade in non-production and validate API and GUI, then add regression tests covering 403-on-denial and API authorization, then promote. Adopting the Bootstrap 5 or Tailwind view sets is a separate, cosmetic change and should follow the security upgrade, not ride along with it.
Maintenance: The rewritten readme plus a real docs/ tree materially lowers onboarding and upgrade cost. roles:install, roles:update and roles:switch with --css/--force make framework selection reproducible in automation. Ongoing cost sits in three places: re-porting views if we customize them, keeping config/roles.php in sync as new keys appear (this release's break is precisely a config key that existed and was ignored — assume others could go live in a later minor), and tracking declared-vs-tested support.
Support: Single maintainer and a very wide declared matrix means we largely self-support on older Laravel and PHP. The Laravel 11 situation is instructive: an upstream advisory made a previously fine combination uninstallable with no package release involved, so installability is a moving target we should probe in CI rather than discover in a deploy. Automate composer audit on a schedule instead of running it per release.
Scaling: The getPermissions() fix removes a query-per-user when the relation is already loaded — meaningful on user-list and admin screens. Authorization still executes on the request path via middleware, so the usual guidance holds: cache role and permission resolution, avoid lazy-loading relations per request, and watch the joins behind level and inheritance resolution under high fan-out. Bulk restore/destroy now run in transactions, trading a little throughput for the elimination of partial writes — correct, but keep admin batch sizes bounded.
Failure modes:
role:admin denies legitimate non-admin callers loudly as 403s; flipping the middleware flag off restores broad authenticated read/write that nobody notices until it is exploited. Both are config-level failures with asymmetric visibility.config:cache looks like the release "didn't work" — add a cache-clear step to the runbook.ROLES_CSS_FRAMEWORK value yields an unstyled, partially broken admin panel.Ramp-up: Low for a Laravel-fluent team — the domain concepts are conventional and now documented end to end. Roughly half a day to a day to install, configure and seed locally; one to two days to upgrade and validate an existing install that has a customized GUI or a live API consumer. The genuinely non-obvious parts are the config-to-behavior mapping and framework selection, both now documented but both worth explicit checklist items in the upgrade runbook.
How can I help you explore Laravel packages today?