bezhansalleh / filament-shield
Filament support for `spatie/laravel-permission`.
Fund package maintenance!
bezhanSalleh
Installs: 1 714 144
Dependents: 88
Suggesters: 0
Security: 0
Stars: 2 496
Watchers: 19
Forks: 253
Open Issues: 1
Requires
- php: ^8.2
- bezhansalleh/filament-plugin-essentials: ^1.0
- filament/filament: ^4.0
- illuminate/contracts: ^11.28|^12.0
- illuminate/support: *
- spatie/laravel-package-tools: ^1.9
- spatie/laravel-permission: ^6.0
Requires (Dev)
- larastan/larastan: ^2.2|^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.0|^8.0
- orchestra/testbench: ^8.0|^9.0|^10.0
- pestphp/pest: ^2.0|^3.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0
- pestphp/pest-plugin-livewire: ^3.0
- pestphp/pest-plugin-type-coverage: ^3.5
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpunit/phpunit: ^10.1|^11.0
- rector/rector: ^2.1
- spatie/laravel-ray: ^1.40
- dev-main
- 4.x-dev
- 4.0.2
- 4.0.1
- 4.0.0
- 4.0.0-beta2
- 4.0.0-beta
- 3.x-dev
- 3.9.10
- 3.3.9
- 3.3.8
- 3.3.7
- 3.3.6
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.6
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.13
- 3.0.12
- 3.0.11
- 3.0.10
- 3.0.9
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 3.0.0-beta2
- 3.0.0-beta1
- 2.x-dev
- v2.5.0
- 2.4.9
- 2.4.8
- 2.4.7
- 2.4.6
- 2.4.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.3
- 2.1.2
- 2.1.1
- v2.1.0
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- 1.x-dev
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2025-09-13 12:44:03 UTC
README
Shield
The easiest and most intuitive way to add access management to your Filament panels.
Important
This iteration is a complete rewrite from versions 3.x and 4.x-beta and is not backward compatible. Please refer to the Upgrade section on how to proceed.
Features
- 🛡️ Complete Authorization Management
- 📦 Resource Permissions
- 📄 Page Permissions
- 🧩 Widget Permissions
- 🛠️ Custom (ad-hoc) permissions
- 🤖 Automatic Policy Generation
- 📜 Default Policy methods for Filament Resources
- 🏷️ Per Resource Policy definition
- 🔗 Third-party resource policy & permission generation
- 👑 Super admin role or gate interception
- 👤 Optional baseline panel user role
- 🔄 Multi-tenancy Support
- 🔍 Entity discovery (across all panels if enabled)
- 🌐 Localized permission & entity labels
- 🌱 Seeder generation (roles + direct permissions)
- 🎨 Intuitive UI
- 🖌️ Publish & customize the built-in resource
- ⚡ Fine-grained CLI tooling with safe prohibiting
Compatibility
Package Version | Filament Version |
---|---|
2.x | 2.x |
4.x | 3.x |
4.x | 4.x |
- Installation
- Usage & Configuration
- Upgrade
- Translations
- Testing
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License
Installation
1. Install Package
composer require bezhansalleh/filament-shield
2. Configure Auth Provider
- Publish the config and set your auth provider model.
php artisan vendor:publish --tag="filament-shield-config"
// config/filament-shield.php return [ // ... 'auth_provider_model' => 'App\\Models\\User', // ... ];
- Add the
HasRoles
trait to your auth provider model:use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; }
3. Setup Shield
Run the setup command (it is interactive and smart):
php artisan shield:setup
Usage & Configuration
The package comes with a sensible default configuration that should work for most applications. You can customize the configuration by modifying it to fit your needs. The following sections explain the various configuration options available.
Permissions
You can customize how permission keys are generated to match your preferred naming conventions and organizational standards. Shield uses these settings from the filament-shield.php
config file when creating permission names from your {Resources|Pages|Widgets}
.
Configuration
'permissions' => [ 'separator' => ':', 'case' => 'pascal', 'generate' => true, ],
Case
Shield formats permission keys using the specified case style. The available options are:
camel
kebab
snake
pascal
(default)upper_snake
Customize permission key composition
You can customize how permission keys are generated by providing your own callback to buildPermissionKeyUsing
in your AppServiceProvider
's boot()
method. The callback receives the following parameters:
string $entity
: The type of entity (e.g., 'Resource', 'Page', 'Widget').string $affix
: The action or method name (e.g., 'viewAny', 'create').string $subject
: The subject or resource name (e.g., 'Post', 'Dashboard').string $case
: The case format specified in the config (e.g., 'pascal').string $separator
: The separator specified in the config (e.g., ':').
-
Now let's consider an example where we want to handle
Resource
entities that handle the sameModel
orModels
with the same name but with different namespaces and directory structures. The Filament Demo has two resources with the same name that handle two different models:App\Filament\Resources\Blog\Categories\CategoryResource
that handlesApp\Models\Blog\Category
App\Filament\Resources\Shop\Categories\CategoryResource
that handlesApp\Models\Shop\Category
By default Shield will generate the same permission keys for both resources which can cause conflicts. To avoid this we can customize the permission key composition to include the navigation group of the resource as part of the permission key. Here's how you can do it:
use BezhanSalleh\FilamentShield\Facades\FilamentShield; use Filament\Resources\Resource; FilamentShield::buildPermissionKeyUsing( function (string $entity, string $affix, string $subject, string $case, string $separator) { if (is_subclass_of($entity, Resource::class) && in_array( needle: $entity, haystack: [ 'App\Filament\Resources\Blog\Categories\CategoryResource', 'App\Filament\Resources\Shop\Categories\CategoryResource' ], strict: true )) { $subject = str($subject) ->prepend($resource::getNavigationGroup()) ->trim() ->toString(); } return FilamentShield::defaultPermissionKeyBuilder( affix: $affix, separator: $separator, subject: $subject, case: $case ); } );
Now when you run the
shield:generate
command, it will generate distinct permission keys for eachCategoryResource
based on their navigation groups:- For
Blog
'sCategoryResource
since its navigation group isBlog
:ViewAny:BlogCategories
View:BlogCategories
Create:BlogCategories
Update:BlogCategories
Delete:BlogCategories
- For
Shop
'sCategoryResource
since it uses a cluster and its navigation group is blank, so it will just use the resourcesubject
configured in the configfilament-shield.resources.subject
which ismodel
by default:ViewAny:Categories
View:Categories
Create:Categories
Update:Categories
Delete:Categories
This approach ensures that each resource has a unique set of permission keys, preventing any conflicts and allowing for more granular access control. You can of course extract the logic to a separate class or function if it gets too complex, but this should give you a good starting point.
Policies
Shield automatically generates policies for your Resources' Models.
Configuration
'policies' => [ 'path' => app_path('Policies'), 'merge' => true, 'generate' => true, 'methods' => [ 'viewAny', 'view', 'create', 'update', 'delete', 'restore', 'forceDelete', 'forceDeleteAny', 'restoreAny', 'replicate', 'reorder', ], 'single_parameter_methods' => [ 'viewAny', 'create', 'deleteAny', 'forceDeleteAny', 'restoreAny', 'reorder', ], ],
Methods
Each policy includes methods defined in the policies.methods
config. You can customize this list to fit your application's needs. Since Filament Resources typically use a standard set of methods, the default configuration should suffice for most applications. If you have specific resources that require additional methods, you can easily add them to the list.
However, it would be best to only include methods that are commonly used across your resources and define any resource-specific methods in the resources.manage
config section. This approach keeps your policies clean and relevant to your application's requirements.
Merge
When policies.merge
is set to true
, Shield will combine the global methods defined in policies.methods
with any resource-specific methods you define in resources.manage
. This ensures that each resource's policy includes both the standard methods and any additional ones you need for that particular resource.
Single Parameter Methods
Some policy methods only require the user instance as a parameter (e.g., viewAny
, create
). These are defined in policies.single_parameter_methods
. Shield will generate these methods accordingly in the policies. When you add new methods or resource-specific methods, ensure to update this list if they also only require the user instance. This helps maintain consistency and clarity in your policy definitions.
Policy Enforcement
Laravel automatically resolves policies for models, but this is not always the case. For instance, if your models are not in the default App\Models
namespace, are nested, or are from third-party plugins, you may need to manually register the policies. You can do this in a service provider's boot()
method:
Gate::policy(Awcodes\Curator\Models\Media::class, App\Policies\MediaPolicy::class);
Tip For your in-app resources' models you can add the following method in the boot()
method to automatically enforce policies, without the need to manually register each policy. This assumes your policies are in the App\Policies
namespace and follow the naming convention of appending Policy
to the model class name. Adjust the str_replace
parameters if your structure differs:
use Illuminate\Support\Facades\Gate; Gate::guessPolicyNamesUsing(function (string $modelClass) { return str_replace('Models', 'Policies', $modelClass) . 'Policy'; });
Resources
Shield derives resource permission keys from configured policy methods. Since Filament Resources
' authorization is handled via policies, generated permissions align with policy methods.
Configuration
'resources' => [ 'subject' => 'model', 'manage' => [ \BezhanSalleh\FilamentShield\Resources\Roles\RoleResource::class => [ 'viewAny', 'view', 'create', 'update', 'delete', ], ], 'exclude' => [ // ], ],
Subject
You can customize the subject used for resource permissions by setting the subject
key in the resources
configuration. The subject can be set to either class
or model
(default is model
).
Manage
You can define resource-specific policy methods in the resources.manage
configuration. This allows you to tailor the permissions for individual resources (in-app or third-party) based on their unique requirements. When you specify methods here, Shield will generate permissions for these methods in addition to the global methods defined in policies.methods
, provided that policies.merge
is set to true
. This ensures that each resource has a comprehensive set of permissions that reflect both standard and resource-specific actions.
Exclude
You can exclude specific resources from permission generation by listing them in the resources.exclude
configuration. This is useful for resources that should always be accessible or do not require permission checks. When a resource is excluded, Shield will skip generating permissions and policy for it.
Pages & Widgets
Both pages and widgets in Filament follow a similar permission model. By default, they require view permissions. You can customize their behavior in the configuration, including subject, prefix, exclusions, and enforcement traits.
Configuration
Pages
'pages' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Pages\Dashboard::class, ], ],
Widgets
'widgets' => [ 'subject' => 'class', 'prefix' => 'view', 'exclude' => [ \Filament\Widgets\AccountWidget::class, \Filament\Widgets\FilamentInfoWidget::class, ], ],
Options
Option | Description |
---|---|
Subject | Determines how the permission subject is generated. • class → Uses the class name (default). • model → Uses the model name (if the entity has a static getModel() method). |
Prefix | Prepended to permission keys for distinction. • Example for Pages: Page:IconLibrary • Example for Widgets: Widget:IncomeWidget . |
Exclude | Entities listed here will be skipped during permission generation. Useful for always-accessible entities like dashboards, account widgets, or system info. |
Permission Enforcement
Use the appropriate Shield trait to automatically enforce permissions. When applied, these traits ensure:
- Navigation or rendering is hidden if the user lacks permission.
- Access to the page/widget is restricted.
Pages
<?php namespace App\Filament\Pages; use ...; use BezhanSalleh\FilamentShield\Traits\HasPageShield; class MyPage extends Page { use HasPageShield; ... }
Widgets
<?php namespace App\Filament\Widgets; use ...; use BezhanSalleh\FilamentShield\Traits\HasWidgetShield; class IncomeWidget extends LineChartWidget { use HasWidgetShield; ... }
Custom Permissions
Most of the time you will have some ad-hoc permissions that don't fit into the Resource
, Page
, or Widget
categories, or you might not want a policy method for them. You can define these under custom_permissions
in the config:
'custom_permissions' => [ 'Impersonate:User' => 'Impersonate User', 'Export:Order' => 'Export Orders', ],
They appear in the Role Resource
's Custom Permissions tab when enabled.
To enable the tab, set shield_resource.tabs.custom_permissions
to true
in the config.
Users (Assigning Roles to Users)
Shield does not come with a way to assign roles to your users out of the box; however, you can easily assign roles to your users using Filament's Forms
Select
or CheckboxList
component. Inside your users Resource
's form, add one of these components and configure them as needed:
- Without Tenancy
// Using Select Component Forms\Components\Select::make('roles') ->relationship('roles', 'name') ->multiple() ->preload() ->searchable(), // Using CheckboxList Component Forms\Components\CheckboxList::make('roles') ->relationship('roles', 'name') ->searchable(),
- With Tenancy
// Using Select Component 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(), // Using CheckboxList Component Forms\Components\CheckboxList::make('roles') ->relationship(name: 'roles', titleAttribute: 'name') ->saveRelationshipsUsing(function (Model $record, $state) { $record->roles()->syncWithPivotValues($state, [config('permission.column_names.team_foreign_key') => getPermissionsTeamId()]); }) ->searchable(),
You can find out more about these components in the Filament Docs
Shield Plugin & Resource
The plugin provides several methods to handle resource-related customizations and overrides without publishing the resource. You can use the plugin as follows:
Navigation
You may use the following methods to customize the navigation of the RoleResource
:
FilamentShieldPlugin::make() ->navigationLabel('Label') // string|Closure|null ->navigationIcon('heroicon-o-home') // string|Closure|null ->activeNavigationIcon('heroicon-s-home') // string|Closure|null ->navigationGroup('Group') // string|Closure|null ->navigationSort(10) // int|Closure|null ->navigationBadge('5') // string|Closure|null ->navigationBadgeColor('success') // string|array|Closure|null ->navigationParentItem('parent.item') // string|Closure|null ->registerNavigation(); // bool|Closure
Labels
You may use the following methods to customize the labels of the RoleResource
:
FilamentShieldPlugin::make() ->modelLabel('Model') // string|Closure|null ->pluralModelLabel('Models') // string|Closure|null ->recordTitleAttribute('name') // string|Closure|null ->titleCaseModelLabel(false); // bool|Closure
Global Search
You may use the following methods to customize the global search related functionality of the RoleResource
:
FilamentShieldPlugin::make() ->globallySearchable(true) // bool|Closure ->globalSearchResultsLimit(50) // int|Closure ->forceGlobalSearchCaseInsensitive(true) // bool|Closure|null ->splitGlobalSearchTerms(false); // bool|Closure
Parent Resource
You may use the following method to set a parent resource for the RoleResource
:
FilamentShieldPlugin::make() ->parentResource(ParentResource::class); // string|Closure|null
Tenancy
You may use the following methods to customize the tenancy related functionality of the RoleResource
:
FilamentShieldPlugin::make() ->scopeToTenant(true) // bool|Closure ->tenantRelationshipName('organization') // string|Closure|null ->tenantOwnershipRelationshipName('owner'); // string|Closure|null
Layout Customization
-
You can easily customize the
Grid
,Section
andCheckboxList
'scolumns()
andcolumnSpan()
without publishing the resource.FilamentShieldPlugin::make() ->gridColumns([ 'default' => 1, 'sm' => 2, 'lg' => 3 ]) ->sectionColumnSpan(1) ->checkboxListColumns([ 'default' => 1, 'sm' => 2, 'lg' => 4, ]) ->resourceCheckboxListColumns([ 'default' => 1, 'sm' => 2, ]),
-
You can also make the resource tab to have a simple view like the other tabs by using the following method:
FilamentShieldPlugin::make() ->simpleResourcePermissionView()
-
When you have localization enabled and setup and you want the permission labels to react to your application's chosen locale/language you can use the following method:
FilamentShieldPlugin::make() ->localizePermissionLabels()
Commands
Prohibited Commands
Since almost all Shield commands are destructive and can cause data loss, they can be prohibited by calling the prohibit
method of the command as follows in a service provider's boot()
method:
use BezhanSalleh\FilamentShield\Facades\FilamentShield; use BezhanSalleh\FilamentShield\Commands; public function boot(): void { // individually prohibit commands 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()); // or prohibit the above commands all at once FilamentShield::prohibitDestructiveCommands($this->app->isProduction()); }
Core Commands
shield:setup [--fresh] [--tenant=] [--force] [--starred] shield:install {panel} [--tenant] shield:generate [--all] [--option=] [--resource=] [--page=] [--widget=] [--exclude] [--ignore-existing-policies] [--panel=] [--relationships] shield:super-admin [--user=] [--panel=] [--tenant=] shield:seeder [--generate] [--option=permissions_via_roles|direct_permissions] [--force] shield:publish --panel={panel} [--cluster=] [--nested] [--force]
Generate Command Options (recap)
--all Generate for all discovered entities --option=policies_and_permissions|policies|permissions|tenant_relationships Override generator mode --resource=FooResource,BarResource Target resources (class basenames) --page=Dashboard,Settings Target pages (basenames) --widget=StatsOverview,SalesChart Target widgets (basenames) --exclude Treat provided entities as exclusions --ignore-existing-policies Force regeneration of already existing policies --panel=admin Panel ID (required when not interactive) --relationships Generate tenancy relationships (panel must have tenancy)
Localization
Shield supports multiple languages out of the box. When enabled, you can provide translated labels for permissions to create a more localized experience for your international users.
Configuration
'localization' => [ 'enabled' => false, 'key' => 'filament-shield::filament-shield', ],
Key
You can translate the permission labels by creating the translations files for your application's
supported locales following Laravel's localization conventions. The translation file can be
named anything you want.
For example, you can create a file named permissions.php
per locale and then set the
localization.key
in the config as localization.key' => 'permissions'
.
Now given that Filament entities(Resources, Pages, Widgets) can be already localized using their own methods, you only need to provide translations for the resource prefixes, page and widget names, and any custom permissions you have defined. For custom permissions, the keys will be the same as you define them, but in snake cased format. To get the list of keys that you need to provide translations for, you can run the following code snippet in Tinker or wherever you want:
use BezhanSalleh\FilamentShield\Facades\FilamentShield; return collect(FilamentShield::getAllResourcePermissionsWithLabels()) ->keys() ->transform( fn($value) => str($value) ->before(config("filament-shield.permissions.separator")) ->snake() ->toString() ) ->merge( collect(FilamentShield::getPages()) ->merge(FilamentShield::getWidgets()) ->flatMap->permissions->keys() ->transform( fn($value) => str($value) ->after(config("filament-shield.permissions.separator")) ->snake() ->toString() ) ) ->merge( collect(FilamentShield::getCustomPermissions()) ->keys() ->transform(fn($value) => str($value)->snake()->toString()) ) ->unique() ->values() ->toArray();
Example output: running the above in the Filament Demo app context, with custom_permissions
=> ['Impersonate:User', 'View:IconLibrary'] will give you the following output:
[ "view_any", "view", "create", "update", "delete", "restore", "force_delete", "force_delete_any", "restore_any", "replicate", "reorder", "products_cluster", "stats_overview_widget", "orders_chart", "customers_chart", "latest_orders", "impersonate:_user", "view:_icon_library", ]
Default
if you want to use the default translations provided by the package for the commonly used set of permissions for resources, you can set the localization.key
in the config as localization.key' => 'filament-shield::filament-shield.resource_permission_prefixes_labels'
and enable localization by setting localization.enabled
to true
.
Upgrade
Upgrading from 3.x|4.0.0-Beta*
versions to 4.x requires careful consideration due to significant changes in the package's architecture and functionality. Here are the key steps and considerations for a successful upgrade:
-
Backup Your Data: Before making any changes, ensure you have a complete backup of your database and application files. This is crucial in case you need to revert to the previous version.
-
Remove Config and Resource: Delete the existing
filament-shield.php
config file and the publishedRoleResource
if you have done so. This is important to avoid conflicts with the new configuration and resource structure. -
Update Composer: Run
composer require bezhansalleh/filament-shield
to update the package to the latest version. -
Publish New Config and Resource: Publish the new configuration file and the
RoleResource
using the following commands:php artisan vendor:publish --tag="filament-shield-config" php artisan shield:publish --panel=admin # you can ignore this if you didn't published the resource previously
-
Adjust Configuration: Review and adjust the new
filament-shield.php
configuration file to match your application's requirements. Pay special attention to the new options and defaults that may differ from the previous version. -
HasShieldPermissions Contract is Deprecated: If you have implemented the
HasShieldPermissions
contract in your resources, consult Policies and Resources sections on how to migrate. If you leave it as is, it will be ignored. -
Clean Slate or Perserve: Decide whether to start fresh with a clean slate or preserve existing roles and permissions.
- Clean Slate: If you choose to start fresh, you can run the following command to and follow along to set up the package from scratch.
php artisan shield:setup --fresh
- Preserve Existing Data: If you want to keep your existing roles and permissions intact, then follow these steps:
- Add the following code to your
AppServiceProvider
'sboot()
method to perserve the the previous versions(3.x|4.x-Beta*) permission pattern:use BezhanSalleh\FilamentShield\Facades\FilamentShield; use Filament\Pages\BasePage as Page; use Filament\Resources\Resource; use Filament\Widgets\Widget; use Illuminate\Support\Str; //... public function boot(): void { FilamentShield::buildPermissionKeyUsing( function (string $entity, string $affix, string $subject, string $case, string $separator) { return match(true) { # if `configurePermissionIdentifierUsing()` was used previously, then this needs to be adjusted accordingly is_subclass_of($entity, Resource::class) => Str::of($affix) ->snake() ->append('_') ->append( Str::of($entity) ->afterLast('\\') ->beforeLast('Resource') ->replace('\\', '') ->snake() ->replace('_', '::') ) ->toString(), is_subclass_of($entity, Page::class) => Str::of('page_') ->append(class_basename($entity)) ->toString(), is_subclass_of($entity, Widget::class) => Str::of('widget_') ->append(class_basename($entity)) ->toString() }; }); }
- If you have used the
configurePermissionIdentifierUsing()
method to customize the permission key composition, then adjust the logic for resources above to match your custom logic. - Running the
shield:generate
command- If your policies are altered or customized, you may need to run the generate command carefully per resource or set of resources to avoid any unwanted side effects. Then manually review and adjust the customized policies as needed. :
php artisan shield:generate --resource=FooResource,BarResource --option=policies
- If you haven't customized your policies then run the following command to ensure that your policies are up to date with the latest version of Shield:
php artisan shield:generate --all --option=policies
- If you have tenancy enabled in your panels and you want to generate the tenancy relationships, you can add the
--relationships
flag to the above commands.
- If your policies are altered or customized, you may need to run the generate command carefully per resource or set of resources to avoid any unwanted side effects. Then manually review and adjust the customized policies as needed. :
- Review and adjust the generated policies and permissions as needed.
- Add the following code to your
- Clean Slate: If you choose to start fresh, you can run the following command to and follow along to set up the package from scratch.
-
Test Thoroughly: After completing the upgrade, thoroughly test your application to ensure that all functionalities related to roles, permissions, and access control are working as expected. Pay special attention to any custom implementations you may have had in place.
Translations
Publish the translations using:
php artisan vendor:publish --tag="filament-shield-translations"
Testing
composer test
Changelog
See CHANGELOG.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.