Filament Shield Documentation
repository·main·Indexed 25 days ago
https://github.com/bezhansalleh/filament-shieldAn access management solution for Filament panels that automates permission and policy management for resources, pages, and widgets. It features automatic policy generation, support for custom ad-hoc permissions, multi-tenancy, and super admin role interception. Compatible with Filament versions 4.x and 5.x.
What's inside Filament Shield
- Filament Shield is an access management package for Filament panels. It provides complete authorization management for Resources, Pages, and Widgets, along with automatic policy generation and support for custom (ad-hoc) permissions. It also supports multi-tenancy, super admin role interception, and localized permission labels.
Setup Shield with the interactive CLI
mainRun the interactive setup command to configure Shield in your application. This command is designed to be smart and guide you through the initial setup process.
php artisan shield:setupConfigure the Auth Provider for Shield
mainTo use Shield, you must configure your authentication provider model (e.g.,
User) to work with the package.- Publish the configuration file:
php artisan vendor:publish --tag="filament-shield-config" - Set the
auth_provider_modelinconfig/filament-shield.phpto your User model class. - Add the
Spati\\Permission\\\|Traits\\\|HasRolestrait to your User model.
php artisan vendor:publish --tag="filament-shield-config"- Publish the configuration file:
Upgrade from 3.x to 4.x
mainUpgrading to 4.x involves significant architectural changes. Follow these steps:
- Backup your database.
- Remove old files: Delete
filament-shield.phpconfig and any publishedRoleResource. - Update: Run
composer require bezhansalleh/filament-shield. - Publish new assets:
php artisan vendor:publish --tag="filament-shield-config"php artisan shield:publish --panel=admin
- Handle Permissions:
- Clean Slate: Run
php artisan shield:setup --fresh. - Preserve Data: If you need to keep existing roles, you must manually add a
FilamentShield::buildPermissionKeyUsing()closure to yourAppServiceProviderto replicate the old permission key pattern (snake_case vs the new pattern).
- Clean Slate: Run
- Regenerate: Run
shield:generateto ensure policies are up to date.
Enforce Shield-generated Policies
mainIf your models are located in directories that Laravel's automatic policy discovery cannot find (such as nested under a custom
policies.pathor for vendor models), you must manually register them.The easiest way is to use the
FilamentShield::enforcePolicies()method in your application'sboot()method within a Service Provider.Features:
- Lazy Evaluation: You can pass a closure to gate enforcement per panel or tenant.
- Exclusions: Use the
exceptparameter to skip specific models. - Priority: Explicit
Gate::policy()registrations always take precedence over Shield's enforcement.
Install Filament Shield via Composer
mainInstall the package using Composer to add it to your project.
composer require bezhansalleh/filament-shieldEnforce Page and Widget Permissions with Traits
mainTo automatically hide navigation items or restrict access to Pages and Widgets based on permissions, use the provided Shield traits within your class.
For Pages: Use the
HasPageShieldtrait.For Widgets: Use the
HasWidgetShieldtrait.// For Pages namespace App\Filament\Pages; use ...; use BezhanSalleh\FilamentShield\Traits\HasPageShield; class MyPage extends Page { use HasPageShield; ... } // For Widgets namespace App\Filament\Widgets; use ...; use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; class IncomeWidget extends LineChartWidget { use HasWidgetShield; }Prohibit destructive Shield commands in production
mainTo prevent accidental data loss in production environments, you can prohibit destructive Shield commands (like
generate,install,setup, etc.) by calling theprohibitmethod in your service provider'sboot()method.You can prohibit commands individually or use the
FilamentShield::prohibitDestructiveCommands()helper to prohibit all of them at once.use BezhanSallehilament-shield//Facades\ use BezhanSalleh\FilamentShield\Commands; public function boot(): void { // Prohibit all destructive commands at once FilamentShield::prohibitDestructiveCommands($this->app->isProduction()); }Define Custom Permissions
mainYou can define ad-hoc permissions that do not belong to
Resource,Page, orWidgetcategories by adding them to thecustom_permissionsarray in your configuration file. These permissions will appear in a Custom Permissions tab within the Role Resource if the tab is enabled.To enable the Custom Permissions tab in the Role Resource, set
shield_resource.tabs.custom_permissionstotruein your configuration.'custom_permissions' => [ 'Impersonate:User' => 'Impersonate User', 'Export:Order' => 'Export Orders', ],Configure Custom Permission Formatting
mainCustom permission keys are formatted based on your
caseandseparatorsettings. Shield's formatter is fault-tolerant and normalizes various input formats (snake_case, kebab-case, camelCase, etc.) before applying the target case.If your permissions are managed by external providers (like Terraform or Keycloak) and must retain their exact key names, set
format_custom_permission_keystofalsein thepermissionsconfiguration block. This prevents any case conversion from being applied to custom permissions.'permissions' => [ 'separator' => ':', 'case' => 'pascal', 'generate' => true, 'format_custom_permission_keys' => false, ],Configure Page and Widget Permissions
mainShield provides permission models for Filament Pages and Widgets. By default, they require
viewpermissions.Pages Configuration
'pages' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Pages\Dashboard::class, ], ],Widgets Configuration
'widgets' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Widgets\AccountWidget::class, \Filament\Widgets\FilamentInfoWidget::class, ], ],Options
subject:class(uses class name) ormodel(usesstatic getModel()).prefix: A string prepended to permission keys (e.g.,Page:IconLibrary).exclude: List of entities to skip.
Configure permission key generation settings
mainYou can customize how permission keys are generated (naming conventions, separators, and casing) in the
filament-shield.phpconfiguration file.Important Compatibility Rule: The
separatormust not conflict with the chosencasedelimiter. For example, using_withsnakeor-withkebabwill throw anInvalidArgumentExceptionbecause the system cannot distinguish the affix from the subject.'permissions' => [ 'separator' => ':', 'case' => 'pascal', 'generate' => true, 'format_custom_permission_keys' => true, ],