Download the PHP package coringawc/filament-acl without Composer
On this page you can find all versions of the php package coringawc/filament-acl. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download coringawc/filament-acl
More information about coringawc/filament-acl
Files in coringawc/filament-acl
Package filament-acl
Short Description Contextual permissions for Filament resources, relation managers, and actions.
License MIT
Homepage https://github.com/coringawc/filament-acl
Informations about the package filament-acl
Filament ACL
coringawc/filament-acl is a Filament v4 or v5 plugin for permission systems that are driven by Resource, RelationManager, Page, and Widget ownership instead of model-derived subjects.
It was designed for complex panels where the same Eloquent model can appear in many different UI contexts and each context may need a different permission namespace.
What It Solves
- Permissions are scoped by Filament owner, not by model class.
- A single model can back many resources without forcing duplicated models or policies.
- Policies can keep using Laravel's native signatures and still receive the Filament permission owner as an extra argument.
- Resources, relation managers, pages, widgets, and custom permissions can all participate in the same permission graph.
- Protected roles such as
super_admincan be hidden from UI and optionally bypass package-level checks. - The package ships with an optional built-in roles and permissions resource.
Screenshot
Core Principles
- Trait-first. No
BaseResourceorBaseRelationManageris required. - Automatic by default. Override methods only when the default subject or ownership is not enough.
- Policy-first. Custom actions continue using Laravel
can()and Filament->authorize(). - Generic. The package does not depend on
filament-shield. - Spatie-compatible. Roles and permissions are stored through
spatie/laravel-permission.
Requirements
- PHP 8.4+
- Laravel 12+
- Filament v4 and v5
- Spatie Laravel Permission
Installation
Install the package:
The quickest setup is the install command:
What the install command does:
- publishes
config/permission.phpwhen it does not already exist - publishes
config/filament-acl.php - publishes the permission migration stub
- detects whether your user model uses
uuid,ulid,string, or integer morph keys - writes that morph-key type into the published package config
- optionally runs migrations
- optionally syncs permissions
- optionally creates or promotes an admin user with the protected role
If config or migration files already exist, the command will not overwrite them silently unless you pass --force.
Manual Publishing
If you prefer the manual route:
Then migrate and sync:
Registering The Plugin
Register the plugin once on each panel:
Useful plugin methods:
strictMode(bool $condition = true)scopeRolesByPanel(bool $condition = true)scopePermissionsByPanel(bool $condition = true)permissionsResource(bool $condition = true)permissionsResourceNavigationLabel(?string $label)permissionsResourceNavigationIcon(string|\BackedEnum|\Illuminate\Contracts\Support\Htmlable|null $icon)permissionsResourceNavigationGroup(string|\UnitEnum|null $group)permissionsResourceNavigationSort(?int $sort)permissionsResourceModelLabel(?string $label)permissionsResourcePluralModelLabel(?string $label)permissionsResourceManagedPanel(string|\BackedEnum|null $panel)permissionsResourceCluster(?string $cluster)configurePermissionsResource(Closure $callback)
Opting In Owners
When filament-acl.integration.require_explicit_opt_in is true, only classes that opt in through the package traits participate in:
- permission syncing
- permission resource discovery
- runtime permission checks
Resource
Relation Manager
Relation Manager Metadata In The Permissions UI
The built-in permissions resource resolves relation-manager tab metadata from Filament's public API instead of relying on getTabComponent() internals:
getTitle(Model $ownerRecord, string $pageClass)is used first when owner context is availablegetRelationshipTitle()is used as fallback when owner context is not availablegetIcon(Model $ownerRecord, string $pageClass)is used for the tab icon- the permission-tab badge reflects the number of permission options synced for that relation manager
If you want the permissions UI to match the real Filament tab, implement getTitle() and getIcon() on the relation manager.
Delegating To A Related Resource
By default, each relation manager maintains its own permission set. If you prefer that a relation manager delegates authorization to a related resource instead:
When enabled, a relation manager that defines a related resource will use that resource's permissions instead of generating its own. Individual relation managers can override this per-class:
Page
Widget
Automatic Subjects
getPermissionSubject() is optional.
By default, the package builds subjects automatically from the Filament owner class, for example:
PostResource->Posts- nested
Posts\Resources\Categories\CategoryResource->PostCategories Users\RelationManagers\PostsRelationManager->UserPostsContentInsightsPage->ContentInsights
Override only when the automatic subject is not what you want:
Extra Owner Methods
These methods are available on the package traits and are all optional.
Custom Actions
Default resource and relation-manager actions are added automatically. getPermissionCustomActions() is only for non-standard actions.
When working with inherited owners, remember that PHP attributes are read from the concrete class only. If a child resource, relation manager, page, or widget still needs PermissionSubject, PermissionActions, CustomPermissionActions, or RegisterPermissions, redeclare the attribute on the child class or override the corresponding method.
Permission Actions
You can replace the full action list either by overriding getPermissionActions() or by using the #[PermissionActions([...])] attribute.
Override this method to completely replace the action list for a specific owner. By default it merges config-driven defaults from filament-acl.policies.methods with any custom actions.
For relation managers, overriding getPermissionActions() is the recommended way to narrow the permission surface when the real table only exposes a subset of the default RM actions. This avoids showing unrelated abilities like associate, attach, or dissociate in the permissions UI for owners that do not use them.
The config-driven defaults are:
Relation managers have their own default action list through filament-acl.relation_managers.actions. The package now ships the full set of Filament-inherent RM abilities by default:
Disable Package Registration For One Owner
When this returns false:
- the owner is ignored by
filament-acl:sync - the owner is hidden from the built-in permissions resource
- package-level permission checks for that owner are skipped
- only your domain checks in the policy keep running
You can also express the same opt-out declaratively:
Share Permissions With Another Owner
Use this when two owners should share the same permission namespace.
Effects:
- the current owner inherits the shared owner's permissions
- the current owner is hidden from the built-in permissions resource
- the shared owner remains the single visible source of truth
This is useful for:
- relation managers that should reuse a nested resource
- duplicate resources that expose the same capability set
- page or widget wrappers that should not create extra permission rows
Target Another Panel
Use this when the owner lives in one panel but its permissions should be generated against another panel's auth guard or panel-scope strategy.
Policies
Policies stay native Laravel policies. The package only adds one extra optional argument at the end: PermissionAction|string|null.
Use ChecksPermission to handle the package check first and then continue with your domain rules:
Single-parameter policy methods such as viewAny() or create() work the same way:
Using Custom Actions
The package does not ship a custom Filament action class. Custom actions keep using Filament's native API.
In visible()
Use Laravel's can() and pass the owner class explicitly:
In authorize()
Pass the owner class directly:
For header actions without a record:
This keeps the policy contract explicit while still feeling like native Filament.
Subject Resolution Strategy
The package provides a SubjectResolutionStrategy enum that defines how permission subjects are derived from owner classes:
Basename— uses the class basename without its suffix (default behavior)Fqcn— uses the full namespace-qualified class nameCustom— delegates entirely to a custom callback
This enum is available at CoringaWc\FilamentAcl\Enums\SubjectResolutionStrategy.
Note: Configuration integration for selecting the strategy via
config/filament-acl.phpis planned.
Built-In Permissions Resource
The package can register an internal role-management resource.
Enable it on a panel:
What it does:
- manages roles
- syncs assigned permissions to roles
- shows resources, relation managers, pages, widgets, and custom permissions
- hides the protected role when configured to do so
- respects shared owners and opt-out owners
- can manage another panel's permission scope
Customizing The Permissions Table
Use configurePermissionsTable() to modify the built-in permissions resource table without overriding the entire resource:
The closure receives a Table instance after all default columns and actions have been applied.
Managing Another Panel
If the permissions resource lives in one panel but should manage another panel's permissions:
If you extend the built-in resource yourself, override:
Pages, Widgets, And Custom Permissions In The UI
The built-in permissions resource supports:
- resources and nested resources
- relation managers
- pages
- widgets
- custom free-form permissions
You can disable tabs independently in config:
Protected Role
The package supports one protected role, usually super_admin.
Config:
When enabled:
- the role is hidden from the built-in permissions resource
- the role is hidden from helper queries such as role selects
Gate::before()can bypass package permission checks for users who hold it- the built-in
RolePolicyprevents editing or deleting that role
Commands
Install
Useful flags:
--force--panel=admin--with-admin-user--migrate--sync
Sync Permissions
This command synchronizes permissions for:
- opted-in resources
- opted-in relation managers
- opted-in pages
- opted-in widgets
- configured custom permissions
Create Or Promote An Admin User
Useful flags:
--user=1[email protected]--name="Admin User"--password=secret--no-permission-sync
By default, package commands are blocked in production. Disable this explicitly only if you really want that behavior:
Panel Scope Strategy
Panel scope is configurable independently for roles and permissions.
This affects:
- database writes
- permission lookups
- role queries
- built-in permissions resource
- sync behavior
You can scope only roles, only permissions, both, or neither.
Custom Permissions
Use config('filament-acl.custom_permissions') for permissions that do not belong to a Filament owner.
Examples:
Translating Custom Permission Labels
The built-in permissions resource wraps every custom permission label with __() before rendering. To support multiple locales, use translation keys as labels instead of literal strings:
Then define the translations in your language files:
If a label is not a translation key (or the key is not found), it will be displayed as-is.
Runtime Customization
You can customize subject generation and permission-key building globally.
Via Facade
If the callback returns null, the package falls back to its default behavior.
Via Container Binding
To replace the entire implementation of a core service (subject resolver, key builder, or permission store), override the contract binding in your AppServiceProvider:
Since your application's service provider registers after the package, the container will use your implementation.
Utilities
CoringaWc\FilamentAcl\Support\Utils exposes reusable helpers for applications that need the same runtime logic outside the package internals.
Frequently useful methods:
Utils::createProtectedRole(?string $panelId = null)Utils::getProtectedRoleName()Utils::isProtectedRole(Model|string $role)Utils::scopeVisibleRoles(Builder $query)Utils::scopeRoleQueryToPanel(Builder $query, ?string $panelId = null)Utils::scopePermissionQueryToPanel(Builder $query, ?string $panelId = null)Utils::resolvePermissionOwnerClass(string $ownerClass)Utils::resolveCustomPermissions(?string $panelId = null)Utils::detectMorphKeyType(?string $userModelClass = null)
PHP Attributes
As an alternative to overriding methods, you can use PHP 8 attributes on your classes:
Attributes are read first. If an attribute is present, the corresponding method override is ignored. If no attribute is present, the method fallback runs as usual.
Available attributes:
| Attribute | Equivalent method | Available on |
|---|---|---|
#[PermissionSubject('...')] |
getPermissionSubject() |
Resource, RelationManager, Page, Widget |
#[SharedPermissionOwner(X::class)] |
getSharedPermissionOwner() |
Resource, RelationManager, Page, Widget |
#[PermissionActions([...])] |
getPermissionActions() |
Resource, RelationManager, Page, Widget |
#[CustomPermissionActions([...])] |
getPermissionCustomActions() |
Resource, RelationManager, Page, Widget |
#[RegisterPermissions(false)] |
shouldRegisterPermissions() |
Resource, RelationManager, Page, Widget |
#[PermissionPanel('admin')] |
getPermissionPanel() |
Resource, RelationManager, Page, Widget |
Permission Resource UI Configuration
The built-in permissions resource UI can be customized via config or plugin fluent methods.
Section Grouping
By default, resource permission sections are grouped by navigation group and cluster:
Or via the plugin fluent API:
When both are disabled, each resource gets its own standalone section.
Section Collapse Behavior
Or via the plugin:
Inner Tabs Orientation
Permission sections use inner tabs that are horizontal by default:
Or via the plugin:
Inner Tabs Container
Inner tabs can be rendered inside a bordered container:
Or via the plugin:
Excluding Owners From Discovery
Relation managers, pages, and widgets can be excluded from permission sync and UI discovery via config:
Excluded classes are ignored even if they use the package traits.
Fluent API Priority
Plugin fluent methods always take priority over config values. This allows different panels to have different UI configurations:
Configuration
config/filament-acl.php is extensively documented inline.
Important areas:
- models
- permission key formatting
- plugin defaults
- built-in permissions resource
- protected role
- command safety
- database strategy
- policy generation
- stubs
- subject overrides
- relation managers
- pages
- widgets
- custom permissions
- integration style
Translations
The package ships with:
enpt_BRpt-BR
Translation keys cover:
- resource labels, navigation, and breadcrumbs
- permission entity type tabs
- section group labels
- section toggle actions (
Select All/Deselect All) - ability labels including relation manager actions (
associate,attach,detach,dissociate, and their_anyvariants)
Ability labels are resolved through filament-acl::filament-acl.permission_labels. The resolver tries both camelCase and snake_case keys before falling back to Str::headline().
You can publish and customize them as usual through Laravel's vendor publishing workflow.
Development
The repository includes a Docker-based workbench with a real Filament panel.
The workbench defaults to:
- locale
pt_BR - faker locale
pt_BR - seeded demo resources, nested resources, pages, widgets, roles, and users
- PHP CLI server with 4 workers for concurrent Livewire requests
Demo users:
[email protected]/password— João Silva (super admin)[email protected]/password— Maria Santos (moderator)[email protected]/password— Carlos Oliveira (posts only)
User names are translated via workbench::workbench.seeds.users.* and follow the active locale.
To start the workbench:
Then open:
The workbench .env overrides testbench.yaml defaults for HTTP serving (file-based SQLite and file session driver). Tests continue using in-memory SQLite from testbench.yaml.
The workbench config files in workbench/config/ are loaded automatically through testbench.yaml (discovers.config: true under the workbench: key). This lets the workbench override package config defaults without touching the published config file.
Testing
Run the package test suite:
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
- Argemiro Dias
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of filament-acl with dependencies
filament/filament Version ^5.0
spatie/laravel-package-tools Version ^1.15
spatie/laravel-permission Version ^7.0