Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
Filament Shield
https://github.com/bezhansalleh/filament-shield
Admin
Filament Shield is a package that provides easy and intuitive access management for Filament Panels,
...
Tokens:
13,730
Snippets:
70
Trust Score:
9.6
Update:
2 weeks ago
Context
Skills
Chat
Benchmark
77.1
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Filament Shield Filament Shield is a comprehensive access management package for Filament PHP admin panels that integrates with Spatie's Laravel Permission package. It provides an intuitive way to manage roles and permissions for Filament Resources, Pages, and Widgets with automatic policy generation, multi-tenancy support, and a built-in Role management UI. The package automatically discovers entities (resources, pages, widgets) across your Filament panels and generates corresponding permissions and policies. It supports super admin roles with gate interception, baseline panel user roles, custom ad-hoc permissions, and localized permission labels in 32+ languages. Shield provides fine-grained CLI tools for generating permissions, policies, and seeders while maintaining flexibility through extensive configuration options. ## Installation Install the package and set up Shield with automatic migrations and configuration. ```bash # Install the package via Composer composer require bezhansalleh/filament-shield # Publish the configuration file php artisan vendor:publish --tag="filament-shield-config" # Run the interactive setup command php artisan shield:setup # Or run setup with fresh migrations php artisan shield:setup --fresh ``` ## Add HasRoles Trait to User Model The User model must use Spatie's HasRoles trait for Shield to function properly. ```php <?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; // ... rest of your model } ``` ## Register FilamentShieldPlugin in Panel Provider Register the Shield plugin in your Filament panel to enable the Role management resource. ```php <?php namespace App\Providers\Filament; use BezhanSalleh\FilamentShield\FilamentShieldPlugin; use Filament\Panel; use Filament\PanelProvider; class AdminPanelProvider extends PanelProvider { public function panel(Panel $panel): Panel { return $panel ->default() ->id('admin') ->path('admin') ->plugins([ FilamentShieldPlugin::make() ->gridColumns([ 'default' => 1, 'sm' => 2, 'lg' => 3 ]) ->sectionColumnSpan(1) ->checkboxListColumns([ 'default' => 1, 'sm' => 2, 'lg' => 4, ]) ->resourceCheckboxListColumns([ 'default' => 1, 'sm' => 2, ]), ]); } } ``` ## Generate Permissions and Policies Use the shield:generate command to create permissions and policies for your Filament entities. ```bash # Generate permissions and policies for all entities in a panel php artisan shield:generate --all --panel=admin # Generate only policies (no permissions) php artisan shield:generate --all --option=policies --panel=admin # Generate only permissions (no policies) php artisan shield:generate --all --option=permissions --panel=admin # Generate for specific resources php artisan shield:generate --resource=UserResource,PostResource --panel=admin # Generate for specific pages php artisan shield:generate --page=Dashboard,Settings --panel=admin # Generate for specific widgets php artisan shield:generate --widget=StatsOverview,SalesChart --panel=admin # Exclude specific entities during generation php artisan shield:generate --all --resource=UserResource --exclude --panel=admin # Regenerate policies even if they exist php artisan shield:generate --all --ignore-existing-policies --panel=admin # Generate with tenancy relationships php artisan shield:generate --all --relationships --panel=admin ``` ## Create Super Admin User Create a super admin user with unrestricted access to the entire application. ```bash # Interactive super admin creation php artisan shield:super-admin --panel=admin # Create super admin for specific user php artisan shield:super-admin --user=1 --panel=admin # Create super admin with specific tenant php artisan shield:super-admin --user=1 --panel=admin --tenant=1 ``` ## HasPageShield Trait for Page Authorization Apply the HasPageShield trait to custom pages to enforce permission-based access control. ```php <?php namespace App\Filament\Pages; use BezhanSalleh\FilamentShield\Traits\HasPageShield; use Filament\Pages\Page; class Analytics extends Page { use HasPageShield; protected static ?string $navigationIcon = 'heroicon-o-chart-bar'; protected static string $view = 'filament.pages.analytics'; // Navigation and access are automatically controlled by permissions // Permission key will be: view:Analytics (based on config) } ``` ## HasWidgetShield Trait for Widget Authorization Apply the HasWidgetShield trait to widgets to control their visibility based on user permissions. ```php <?php namespace App\Filament\Widgets; use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; use Filament\Widgets\StatsOverviewWidget; use Filament\Widgets\StatsOverviewWidget\Stat; class IncomeWidget extends StatsOverviewWidget { use HasWidgetShield; protected function getStats(): array { return [ Stat::make('Total Revenue', '$192,000'), Stat::make('Monthly Growth', '+12%'), Stat::make('Active Users', '1,234'), ]; } // Widget rendering is automatically controlled by permissions // Permission key will be: view:IncomeWidget (based on config) } ``` ## HasPanelShield Trait for Panel Access Apply the HasPanelShield trait to your User model to control panel access based on roles. ```php <?php namespace App\Models; use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; use HasPanelShield; // Users with super_admin or panel_user role can access the panel // The canAccessPanel method is automatically implemented } ``` ## Custom Permission Key Builder Customize how permission keys are generated by providing a custom callback in your AppServiceProvider. ```php <?php namespace App\Providers; use BezhanSalleh\FilamentShield\Facades\FilamentShield; use Filament\Resources\Resource; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot(): void { FilamentShield::buildPermissionKeyUsing( function (string $entity, string $affix, string $subject, string $case, string $separator) { // Handle resources with the same name but different namespaces if (is_subclass_of($entity, Resource::class)) { $resource = resolve($entity); $navigationGroup = $resource::getNavigationGroup(); if ($navigationGroup) { $subject = str($subject) ->prepend($navigationGroup) ->trim() ->toString(); } } // Use the default builder with modified subject return FilamentShield::defaultPermissionKeyBuilder( affix: $affix, separator: $separator, subject: $subject, case: $case ); } ); } } ``` ## Assign Roles to Users in Resource Forms Use Filament form components to assign roles to users within your User resource. ```php <?php namespace App\Filament\Resources; use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\Resource; class UserResource extends Resource { public static function form(Form $form): Form { return $form->schema([ Forms\Components\TextInput::make('name') ->required(), Forms\Components\TextInput::make('email') ->email() ->required(), // Using Select component for role assignment Forms\Components\Select::make('roles') ->relationship('roles', 'name') ->multiple() ->preload() ->searchable(), // Or using CheckboxList component Forms\Components\CheckboxList::make('roles') ->relationship('roles', 'name') ->searchable() ->columns(2), ]); } } ``` ## Assign Roles with Multi-Tenancy Support When using multi-tenancy, sync roles with the tenant's team foreign key. ```php <?php namespace App\Filament\Resources; use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\Resource; use Illuminate\Database\Eloquent\Model; class UserResource extends Resource { public static function form(Form $form): Form { return $form->schema([ Forms\Components\TextInput::make('name') ->required(), Forms\Components\TextInput::make('email') ->email() ->required(), // Role assignment with tenancy support Forms\Components\Select::make('roles') ->relationship('roles', 'name') ->saveRelationshipsUsing(function (Model $record, $state) { $record->roles()->syncWithPivotValues( $state, [config('permission.column_names.team_foreign_key') => getPermissionsTeamId()] ); }) ->multiple() ->preload() ->searchable(), ]); } } ``` ## Prohibit Destructive Commands in Production Prevent potentially destructive Shield commands from running in production environments. ```php <?php namespace App\Providers; use BezhanSalleh\FilamentShield\Facades\FilamentShield; use BezhanSalleh\FilamentShield\Commands; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot(): void { // Prohibit all destructive commands at once FilamentShield::prohibitDestructiveCommands($this->app->isProduction()); // Or prohibit commands individually Commands\GenerateCommand::prohibit($this->app->isProduction()); Commands\InstallCommand::prohibit($this->app->isProduction()); Commands\PublishCommand::prohibit($this->app->isProduction()); Commands\SetupCommand::prohibit($this->app->isProduction()); Commands\SeederCommand::prohibit($this->app->isProduction()); Commands\SuperAdminCommand::prohibit($this->app->isProduction()); } } ``` ## Plugin Navigation Customization Customize the Shield Role resource navigation appearance in your panel. ```php <?php use BezhanSalleh\FilamentShield\FilamentShieldPlugin; FilamentShieldPlugin::make() ->navigationLabel('Access Control') ->navigationIcon('heroicon-o-shield-check') ->activeNavigationIcon('heroicon-s-shield-check') ->navigationGroup('Settings') ->navigationSort(10) ->navigationBadge('5') ->navigationBadgeColor('success') ->registerNavigation(true); ``` ## Plugin Labels and Search Customization Customize model labels and global search behavior for the Role resource. ```php <?php use BezhanSalleh\FilamentShield\FilamentShieldPlugin; FilamentShieldPlugin::make() ->modelLabel('Role') ->pluralModelLabel('Roles') ->recordTitleAttribute('name') ->titleCaseModelLabel(true) ->globallySearchable(true) ->globalSearchResultsLimit(50) ->forceGlobalSearchCaseInsensitive(true) ->splitGlobalSearchTerms(false); ``` ## Plugin Tenancy Configuration Configure Shield for multi-tenant applications with tenant-scoped roles. ```php <?php use BezhanSalleh\FilamentShield\FilamentShieldPlugin; FilamentShieldPlugin::make() ->scopeToTenant(true) ->tenantRelationshipName('organization') ->tenantOwnershipRelationshipName('owner'); ``` ## Localized Permission Labels Enable localized permission labels and generate translation files for different locales. ```php <?php use BezhanSalleh\FilamentShield\FilamentShieldPlugin; // In your panel provider FilamentShieldPlugin::make() ->localizePermissionLabels(); ``` ```bash # Generate translation file for a specific locale php artisan shield:translation en --panel=admin php artisan shield:translation es --panel=admin php artisan shield:translation fr --panel=admin ``` ```php <?php // lang/en/shield-permissions.php (generated file) return [ // Resource affixes 'create' => 'Create', 'delete' => 'Delete', 'delete_any' => 'Delete Any', 'force_delete' => 'Force Delete', 'force_delete_any' => 'Force Delete Any', 'replicate' => 'Replicate', 'reorder' => 'Reorder', 'restore' => 'Restore', 'restore_any' => 'Restore Any', 'update' => 'Update', 'view' => 'View', 'view_any' => 'View Any', // Pages 'view_dashboard' => 'Dashboard', // Widgets 'view_stats_overview' => 'Stats Overview', // Custom permissions 'approve_posts' => 'Approve Posts', ]; ``` ## Generate Permission Seeder Generate a seeder file to export and restore roles and permissions. ```bash # Generate seeder with permissions via roles php artisan shield:seeder --generate --option=permissions_via_roles # Generate seeder with direct permissions php artisan shield:seeder --generate --option=direct_permissions # Generate seeder with user data php artisan shield:seeder --generate --with-users # Force overwrite existing seeder php artisan shield:seeder --generate --force ``` ## Configuration Reference Configure Shield behavior through the config/filament-shield.php file. ```php <?php // config/filament-shield.php return [ // Role resource settings 'shield_resource' => [ 'slug' => 'shield/roles', 'show_model_path' => true, 'cluster' => null, 'tabs' => [ 'pages' => true, 'widgets' => true, 'resources' => true, 'custom_permissions' => false, // Enable to show custom permissions tab ], ], // Multi-tenancy configuration 'tenant_model' => null, // e.g., 'App\\Models\\Team' // User model for role assignments 'auth_provider_model' => 'App\\Models\\User', // Super admin configuration 'super_admin' => [ 'enabled' => true, 'name' => 'super_admin', 'define_via_gate' => false, 'intercept_gate' => 'before', ], // Panel user configuration 'panel_user' => [ 'enabled' => true, 'name' => 'panel_user', ], // Permission key generation 'permissions' => [ 'separator' => ':', // Separator between affix and subject 'case' => 'pascal', // pascal, camel, snake, kebab, upper_snake 'generate' => true, ], // Policy generation settings 'policies' => [ 'path' => app_path('Policies'), 'merge' => true, // Merge global methods with resource-specific 'generate' => true, 'methods' => [ 'viewAny', 'view', 'create', 'update', 'delete', 'deleteAny', 'restore', 'forceDelete', 'forceDeleteAny', 'restoreAny', 'replicate', 'reorder', ], 'single_parameter_methods' => [ 'viewAny', 'create', 'deleteAny', 'forceDeleteAny', 'restoreAny', 'reorder', ], ], // Localization settings 'localization' => [ 'enabled' => false, 'key' => 'shield-permissions', ], // Resource permission settings 'resources' => [ 'subject' => 'model', // 'model' or 'class' 'manage' => [ // Override methods for specific resources // App\Filament\Resources\PostResource::class => ['viewAny', 'view', 'create'], ], 'exclude' => [ // Resources to exclude from permission generation ], ], // Page permission settings 'pages' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Pages\Dashboard::class, ], ], // Widget permission settings 'widgets' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Widgets\AccountWidget::class, \Filament\Widgets\FilamentInfoWidget::class, ], ], // Custom ad-hoc permissions 'custom_permissions' => [ // 'Impersonate:User' => 'Impersonate User', // 'Export:Order' => 'Export Orders', ], // Entity discovery across panels 'discovery' => [ 'discover_all_resources' => false, 'discover_all_widgets' => false, 'discover_all_pages' => false, ], // Role policy auto-registration 'register_role_policy' => true, ]; ``` ## Policy Enforcement with Gate Register policies manually for models outside the default namespace or from third-party packages. ```php <?php namespace App\Providers; use Illuminate\Support\Facades\Gate; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot(): void { // Register policy for third-party package model Gate::policy( \Awcodes\Curator\Models\Media::class, \App\Policies\MediaPolicy::class ); // Auto-register policies based on naming convention Gate::guessPolicyNamesUsing(function (string $modelClass) { return str_replace('Models', 'Policies', $modelClass) . 'Policy'; }); } } ``` ## Publish and Customize Role Resource Publish the Role resource to customize its appearance and behavior. ```bash # Publish Role resource for a specific panel php artisan shield:publish --panel=admin # Publish with cluster support php artisan shield:publish --panel=admin --cluster=Settings # Publish as nested resource php artisan shield:publish --panel=admin --nested # Force overwrite existing published resource php artisan shield:publish --panel=admin --force ``` Filament Shield is primarily designed for Filament PHP admin panel applications that require role-based access control (RBAC). Common use cases include multi-user admin panels where different user roles need varying levels of access to resources, pages, and widgets. It's ideal for SaaS applications with multi-tenancy requirements, content management systems with editorial workflows, e-commerce backends with staff role management, and any Laravel application using Filament that needs granular permission control. The package integrates seamlessly with Filament's authorization system through Laravel's Gate and Policy mechanisms. Resources automatically respect policies generated by Shield, while Pages and Widgets can be protected using the provided traits. For advanced scenarios, developers can customize permission key generation, define custom permissions for actions not tied to CRUD operations, and extend the built-in Role resource. The CLI tools support CI/CD pipelines with non-interactive modes and seeder generation for consistent deployments across environments.