laravel-enso/roles
Role management for Laravel Enso: create and edit roles, attach permissions, and assign users. Integrates with Enso’s authorization, menus, and user management to control access across the application. Provides CRUD operations and configuration for role-based access control in Enso admin apps.
The roles package is part of the Enso admin suite and assumes you are (or will be) running Laravel Enso; it is not really a drop-in standalone package. It pairs with laravel-enso/permissions (usually pulled in transitively) and, in most apps, you install it via the Enso installer or by requiring it after laravel-enso/core.
Minimal setup:
composer require laravel-enso/roles
php artisan migrate
php artisan db:seed --class="LaravelEnso\Roles\Database\Seeders\RolesSeeder"
The service provider is auto-discovered, migrations are auto-loaded, and a Roles menu entry appears under Administration once Enso's frontend assets are built.
Where to look first:
src/Models/Role.php — name, slug/description, permissions() belongsToMany, users() relation.src/Services/RoleService.php — the canonical create/update/destroy path.src/Policies/RolePolicy.php — what admins may do to roles.config/ (or config/enso/*.php) — model overrides and menu registration.client/src — Vue components and Vuex store used by the admin UI.First real use case: give a user a role and let the permission gate take over.
$user->role()->associate(Role::whereName('admin')->first())->save();
// thereafter
$user->can('core.users.index'); // resolved from role → permissions
Enso models users with a single role_id, not a role pivot table, which shapes everything below.
Single-role assignment. Because users carry role_id, assignment is a belongsTo operation, not sync():
$user->update(['role_id' => $role->id]);
// or
$user->role()->associate($role)->save();
To change a user's role from the UI, hit the built-in Enso users controller; to do it programmatically from a form request, wrap it in a small service rather than sprinkling role_id writes.
Permission allocation. Roles own permissions via the standard pivot:
$role->permissions()->sync($permissionIds);
$role->permissions()->attach($permission->id);
$role->permissions()->detach($permission->id);
Prefer routing this through RoleService (or a command) so listeners/observers and any cache invalidation fire consistently.
Authorization. Enso wires roles into Laravel's gate: $user->can('action.name') works because each permission is registered as an ability, and the admin role is granted everything (Enso's Gate::before shortcut). Use policies for CRUD on your own models and can() checks in Blade/Vue for UI affordances.
Admin CRUD via the service. When building custom screens or endpoints, mirror what the package's controller does:
(new RoleService())->store($request->validated());
(new RoleService())->update($role, $request->validated());
This keeps validation, policy events, and pivot syncing in one place, and means future package upgrades don't silently skip behavior you forgot to replicate.
Extending the model. Publish config/migrations, add columns (e.g. is_system), and point the package at a subclass:
// config/enso/roles.php (or equivalent)
'model' => App\Models\Role::class,
Subclass LaravelEnso\Roles\Models\Role, keep $fillable and relationships intact, and layer scopes/accessors on top.
Frontend customization. The roles UI lives under this package's client/src (Vuex module + components). Fork the store actions or extend the tables via Enso's resource conventions — don't edit vendor files; publish the assets and override.
laravel-enso/permissions, or add a custom pivot and duplicate the gate logic. Don't assume $user->roles() exists.php artisan enso:clear (or cache:clear) in your deploy/rollout for permission changes, and never assume a role update is visible instantly.role_id = null; your app must treat "no role" as no abilities rather than crashing on $user->role->name. Seed a fallback role or block deletion in a custom policy.roles and permissions to exist before users.role_id is added. Late installs need a small follow-up migration to add the FK and backfill existing users, rather than rerunning the package's seeders blindly.RolesSeeder ships admin/supervisor and demo roles. Running it on production is fine, but re-running the permission seeder can resurrect permissions you deliberately removed — audit before re-seeding.ValidateRoleRequest enforces name uniqueness and pivot shape; if you build a custom endpoint, reuse it or you'll drift from the UI's behavior (and its error messages).$user->role?->permissions->pluck('name') and compare against the string passed to can(). Ninety percent of "roles don't work" reports are a typo in the ability name or a stale cache, not a missing pivot row.Gate::before(fn () => true)) for convenience, but keep at least a few tests exercising a non-admin role so regressions in permission wiring surface.laravel-enso/core, permissions, and roles to compatible versions. Mixing minor versions of permissions and roles is a common source of "permission not found" errors after composer update.How can I help you explore Laravel packages today?