bart2004 / filament-dynamic-roles-and-permissions
Role-based access control for Filament with resource-, field- and action-level permissions.
Package info
github.com/bart2004/filament-dynamic-roles-and-permissions
pkg:composer/bart2004/filament-dynamic-roles-and-permissions
Requires
- php: ^8.4
- filament/filament: ^5.0
- illuminate/contracts: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.24
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-18 21:53:57 UTC
README
Role-based access control for Filament with three levels of granularity:
- Resource level — which CRUD actions a role may perform per resource (
viewAny,view,create,update,delete,restore,forceDelete). - Field level — the access level of each form field, table column and infolist entry per role (
Mutable,Read Only,Fill Only,Hidden), configured independently for the create form, the edit form, the table and the infolist. - Action level — the visibility of header, row and bulk actions per role (
Visible,Disabled,Hidden).
Each user is assigned a single role. Permissions are edited through a Roles resource that introspects every registered Filament resource, so new resources and fields appear automatically.
Requirements
- PHP 8.4+
- Laravel 12 or 13
- Filament v5
Installation
composer require bart2004/filament-dynamic-roles-and-permissions
The package migrations are loaded automatically. Apply them with:
php artisan migrate
They create the roles, resource_permissions, field_permissions and action_permissions tables and add a nullable role_id column to your users table.
Publishing the migrations (optional)
If you want to customise the schema, publish the migrations into your own database/migrations directory:
php artisan vendor:publish --tag=filament-dynamic-roles-and-permissions-migrations php artisan migrate
Once published, the package stops loading its bundled migrations, so the published copies are the single source of truth (no duplicate runs).
Publishing the config (optional)
php artisan vendor:publish --tag=filament-dynamic-roles-and-permissions-config
Setup
1. Register the plugin
Add the plugin to your panel provider:
use BartStrik\FilamentDynamicRolesAndPermissions\FilamentDynamicRolesAndPermissionsPlugin; public function panel(Panel $panel): Panel { return $panel // ... ->plugin(FilamentDynamicRolesAndPermissionsPlugin::make()); }
This registers the Roles resource in the panel.
2. Add the trait to your User model
use BartStrik\FilamentDynamicRolesAndPermissions\Concerns\HasRolePermissions; class User extends Authenticatable { use HasRolePermissions; }
The trait adds a role() relationship and an isSuperAdmin() method. Override isSuperAdmin() to grant unrestricted access:
public function isSuperAdmin(): bool { return $this->email === 'admin@example.com'; }
3. Resource permissions are enforced automatically
That's it — there's nothing to wire up per resource. Field- and action-level
permissions are enforced at render time, and resource-level abilities
(viewAny, view, create, update, delete, restore, forceDelete, plus
their bulk *Any variants) are authorized automatically for every Filament
resource from the current role's stored permissions.
Under the hood this registers a single Gate::before hook that maps each model
back to its Filament resource, so you no longer write a policy class per model.
Overriding a single resource
The automatic check steps aside for any model that already has its own policy
(registered explicitly, or discovered by Laravel's App\Policies\{Model}Policy
naming convention). So to customise one resource, just write a normal policy —
optionally extending the base policy to keep the role-based checks for the
abilities you don't override:
use BartStrik\FilamentDynamicRolesAndPermissions\Policies\ResourcePermissionPolicy; class PostPolicy extends ResourcePermissionPolicy { protected function resourceClass(): string { return \App\Filament\Resources\Posts\PostResource::class; } // Override just the abilities you need; the rest stay role-driven. public function delete($user, $model): bool { return false; } }
To turn the automatic behaviour off entirely and manage every policy yourself,
set auto_register_policies to false in the config.
How it works
ResourcePermission,FieldPermissionandActionPermissionstore the settings per role.PermissionCacheServicecaches each role's permissions forever and is cleared whenever a role is saved.Support\DynamicPermissionshooks into Filament'sField,ColumnandEntryconfiguration to apply the cached access levels when a component renders.Authorization\ResourcePermissionGateregisters aGate::beforehook that authorizes the standard resource abilities for every Filament resource, deferring to any policy you've written yourself.
Access levels
| Level | Form field | Table / Infolist |
|---|---|---|
Mutable |
Editable | Visible |
Read Only |
Disabled (visible, not editable) | Visible |
Fill Only |
Editable on create, disabled on edit | — |
Hidden |
Hidden | Hidden |
Configuration
// config/filament-dynamic-roles-and-permissions.php return [ 'navigation' => [ 'group' => null, // Navigation group for the Roles resource 'sort' => null, // Navigation sort order ], // Authorize resource abilities automatically for every Filament resource. // Set to false to write and register every policy yourself. 'auto_register_policies' => true, ];
Testing
composer test
License
MIT