Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Acl Laravel Package

coringawc/filament-acl

Role and permission management for Filament panels. coringawc/filament-acl adds ACL resources to create roles, assign permissions, and control access to your admin resources, pages, and widgets, integrating with Laravel's authorization layer for straightforward access control.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. coringawc/filament-acl is a trait-first authorization layer for Filament v5 panels. Its architecture is deliberately narrow: it treats the Filament owner (Resource, RelationManager, Page, Widget, or a free-form custom permission) as the permission subject, discovers opted-in owners, generates permission keys, syncs them into a Spatie permission store, and ships a built-in role/permission management resource. Consumption is via opt-in traits — HasResourcePermissions, HasRelationManagerPermissions, HasPagePermissions, HasWidgetPermissions — with optional method overrides (getPermissionSubject(), shouldRegisterPermissions(), getSharedPermissionOwner(), getPermissionActions(), getPermissionCustomActions(), getPermissionPanel()) rather than required base classes or static properties. That is a good fit for an existing Filament application: adoption is additive and per-owner, not a wholesale rebase onto package-provided base classes. The package is explicitly decoupled from filament-shield (no Composer dependency, no runtime calls, no config contract assuming Shield's presence), which removes the most common source of coupling risk in this category and means it can coexist with a Shield-based panel during a transition. It also keeps domain policy logic out of scope, which is the right boundary — it means the package does not compete with our application policies, it feeds them.

Integration feasibility. Feasible with a well-understood envelope. Hard constraints are Spatie ^8.2, PHP ^8.3, and Filament ^5.0 — these are floors, not tested ceilings, and the release notes state plainly that Laravel 13 and PHP 8.5 were not tested. Two integration surfaces require deliberate app-side work rather than being purely drop-in:

  1. Policy contract. Policies remain native Laravel policies; package checks are opt-in via ChecksPermission, with the extra PermissionAction|string|null $permissionAction argument kept last in the signature (viewAny(mixed $user, PermissionAction|string|null $permissionAction = null), update(mixed $user, Model $record, PermissionAction|string|null $permissionAction = null)). Every policied model must be touched to thread that argument through, and the guidance is explicit that policies must not infer the owner from the request or route when it can be passed explicitly. This is mechanical but repo-wide.
  2. Attribute resolution is concrete-class only. #[PermissionSubject], #[PermissionActions], #[CustomPermissionActions], and #[RegisterPermissions(false)] are not inherited. Any resource inheritance hierarchy in our codebase must redeclare attributes or override methods on each child. This is the single most likely source of silent misconfiguration — a subclass will appear correctly wired and simply not carry its parent's permission metadata.

Custom actions stay native (auth()->user()?->can('archive', [$record, PostResource::class]), ->authorize('archive', PostResource::class)), and the package deliberately avoids shipping a custom Filament action class. That is a genuine feasibility positive: no new UI primitive to learn, review, or maintain.

Technical risk. Rated low-to-moderate, and the risks are mostly process rather than runtime:

  • Zero community signal. 0 stars is not a quality verdict, but it is an absent independent-validation signal. Combined with a package-maintainer-authored validation narrative, our review cannot lean on third-party adoption as a proxy for production hardening.
  • Version ceilings unproven, not disproven. Laravel 13 / PHP 8.5 incompatibility is unknown. The release notes are commendably explicit about this, but it means our platform-upgrade timeline cannot assume this dependency keeps pace.
  • Authorization is a security-boundary surface. Bugs here are fail-open or fail-closed in ways that unit tests catch only if the tests are adversarial. The opt-in/opt-out semantics are the critical invariant: require_explicit_opt_in = true by default, and an owner returning shouldRegisterPermissions(): false must not be synced, must not appear in the permission UI, and must have package-level checks skipped. A regression in that third clause is a silent permission bypass, and the AGENTS.md flags it as "essential. Do not regress it" — meaning it has been a live regression risk.
  • Shared-owner and panel-scope behavior are coupled. Shared owners (getSharedPermissionOwner()) inherit permissions and should normally disappear from discovery and the permission UI in favor of the canonical owner. Panel scope is configurable separately for roles and permissions, and the AGENTS.md requires changes to propagate consistently across sync commands, built-in resource queries, hidden-role helpers, permission lookup helpers, and protected-role assignment. Five layers that must move together is a coordination hazard we will inherit as operators, particularly if we configure different panels.
  • Protected role is intentionally special. Hidden from package UI, optionally bypasses package checks via Gate::before(), protected from edit/delete by RolePolicy, assignable via an admin-user command. A Gate::before() bypass is exactly the kind of thing that must be reviewed by someone who understands the blast radius before it is enabled in production.
  • Supply-chain posture is genuinely strong. All 12 third-party GitHub Actions pinned to verified commit SHAs, three-day cooldowns on version updates with immediate security updates, Dependabot-managed Composer monitoring, actionlint and SHA/config checks in CI. This is the evidence procurement and security reviewers ask for, and it materially offsets the low-star concern.
  • Validation breadth is real. 176 Pest tests / 461 assertions locally; Pest, PHPStan, Pint, and distributed Boost skills green across eight CI jobs spanning PHP 8.3/8.4, Ubuntu and Windows, and minimum/current dependency versions; Copilot review approved with zero findings. A behavior-preserving patch with this matrix is about as safe a dependency bump as exists.
  • Health score is pending. The prior 71.76/100 failed three criteria; v2.0.1 is the remediation, and the new score must be read from the service after re-evaluation. If intake gates on a numeric threshold, the correct status is "pending re-score," not "approved."

Key questions. For the maintainer: (1) Is Laravel 13 / PHP 8.5 support on a roadmap, and what is the compatibility policy — does the package track Filament majors on release, on a lag, or reactively? (2) What is the tested ceiling for Spatie 8.x, and is a Spatie 9 migration anticipated? (3) How is the shouldRegisterPermissions(): false skip-check invariant covered by tests — is there an explicit adversarial test asserting no package-level check runs for opted-out owners? (4) Is the protected-role Gate::before() bypass covered by a test asserting it cannot be enabled for a role that is not hidden/configured? (5) What is the intended behavior when a shared owner points at a class that is itself opted out? For us: (6) Which panel(s) do we scope roles versus permissions to, and do we intend to manage another panel via getManagedPermissionPanel()? (7) How many resource subclasses inherit Filament owners today, and who owns redeclaring attributes on each? (8) Do we have a policy that forbids agent tooling — the two Laravel Boost skills ship in the validation matrix and become content we carry but did not author or test.

Integration Approach

Stack fit. This package is a clean fit only if our declared baseline matches its tested envelope: PHP 8.3+, Filament 5, Spatie ^8.2. If we are on Filament 4 or earlier, below PHP 8.3, or an older Spatie major, the declared constraints rule us out and the conversation ends. Assuming we qualify, the fit is architecturally conservative — traits instead of base classes, native Laravel policies, native Filament authorization, no Shield coupling — which means it composes with our existing code rather than displacing it, and it can be evaluated behind a flag on a single panel before any broad commitment.

Migration path. Adoption is incremental by design, and that is the main reason to prefer it over a bespoke build. The sequence I would run:

  1. Foundation. Confirm and pin Spatie ^8.2 and verify the existing permission tables and config are in a known-good state. Install the package, publish config, and confirm filament-acl.integration.require_explicit_opt_in remains true — do not relax the opt-in default to make onboarding feel faster; the explicit opt-in is the safety property.
  2. Pilot owner. Pick one low-blast-radius Resource. Add HasResourcePermissions, run the sync command, and confirm the generated permission keys appear in the built-in role/permission resource. This validates discovery, key generation, and store writes in one step.
  3. Policy thread-through. Update that Resource's policy to the ChecksPermission pattern with the extra $permissionAction argument last, and write a negative test asserting denial when the permission is absent. Policy changes, not package installation, are the bulk of the effort.
  4. Opt-out verification. Add a second owner that returns shouldRegisterPermissions(): false and assert, with a test, that it is absent from sync, absent from the permission UI, and that package-level checks are skipped. This is the invariant most worth locking down early because regressions here are silent.
  5. Broaden by owner type. Extend in order: remaining Resources, then RelationManagers, then Pages, then Widgets. Each trait has its own surface; validating one type thoroughly before moving to the next keeps the failure domain small.
  6. Shared owners and panel scope. Only after the four owner types are wired, introduce getSharedPermissionOwner() and any non-default getPermissionPanel() / getManagedPermissionPanel() configuration. Because panel scope for roles and permissions is configured separately and must stay consistent across sync commands, resource queries, hidden-role helpers, lookup helpers, and protected-role assignment, this is the stage to re-run the full sync and diff the resulting permission set rather than assume convergence.
  7. Protected role. Configure the protected role last, decide explicitly whether the Gate::before() bypass is enabled, and get that decision reviewed. Verify it is hidden from normal selects and package tables and that RolePolicy blocks edit/delete.
  8. Custom permissions and custom actions. Introduce free-form custom permissions and the custom-action contract (can('archive', [$record, PostResource::class])) only once the resource-driven permissions are stable, so that any authorization surprise is attributable to one change.

Compatibility. Two hard gates and one soft gate. Hard: PHP 8.3+ and Filament 5. Hard: Spatie ^8.2. Soft and unproven: Laravel 13 and PHP 8.5 — treat these as unsupported until demonstrated, and keep this package off the critical path of any Laravel 13 upgrade plan. Also confirm the attribute non-inheritance rule against our resource hierarchy before rollout; if we have deep Filament inheritance, budget the redeclaration work explicitly rather than discovering it in review.

Sequencing. Land the dependency bump as a routine change — it is behavior-preserving, so it does not need its own regression cycle. Then run the pilot → policy → opt-out → broaden → shared-owner/panel-scope → protected-role sequence above as a timeboxed spike, with the go/no-go decision at the end of step 4. If the opt-out invariant holds under test and the policy thread-through is as mechanical as it appears, the remaining steps are execution, not risk. If either is messier than expected, we still have the option to stop at one panel with no architectural debt — which is the advantage a trait-first package buys us.

Operational Impact

Maintenance. The maintainer's posture is the strongest signal in this package's favor and the main reason maintenance burden on us is likely low. All 12 third-party GitHub Actions are pinned to verified commit SHAs; Dependabot monitors Composer and Actions weekly with an explicit three-day version-update cooldown while security updates remain immediate; CI runs Pest, PHPStan, Pint, actionlint, SHA/config verification, and distributed Boost skills across eight jobs. Patch releases are behavior-preserving with stable public APIs — v2.0.1 changed zero runtime behavior, which is exactly the property we need from a long-lived pinned dependency. The residual maintenance risk is upstream compatibility drift, not neglect: the package must track Filament majors and Spatie majors, and there is no published commitment on latency. We should carry an owned watchlist item for Laravel 13 / PHP 8.5 rather than assume the maintainer's timeline matches ours.

Support. Two considerations. First, 0 stars and no evident third-party adoption means our engineers are effectively the first line of support; we cannot assume Stack Overflow coverage or a body of community answers, so the AGENTS.md and the shipped Boost skills become primary documentation — which is a real asset but also content we did not author and must validate ourselves. Second, if our policy forbids agent tooling, we should confirm the Boost skills are inert (installed but unused) rather than assume they can be excluded cleanly from the shipped surface, since they are part of the validated matrix.

Scaling. Permission sync is a batch operation over discovered owners, so cost scales with the number of opted-in Filament owners and the size of the permission set, not with user count — this is a low-scaling-risk component. Two scaling dimensions do need attention: (1) panel count — panel scope is configured separately for roles and permissions, so as we add panels, the configuration matrix grows combinatorially and each new panel is a chance to break the five-layer consistency requirement; (2) permission-key cardinality — free-form custom permissions plus per-owner action keys can inflate the permission table, so I would avoid using custom permissions as a general-purpose feature-flag mechanism. The Gate::before() protected-role bypass is constant-time and not a scaling concern, but it is a correctness concern at any scale.

Failure modes. Ranked by severity, because this is an authorization surface:

  • Fail-open via opt-out regression — an owner returning shouldRegisterPermissions(): false still receiving package-level checks, or worse, being silently treated as permitted. Highest severity, silent, and explicitly flagged upstream as a do-not-regress invariant.
  • Fail-closed via attribute non-inheritance — a subclass resource silently lacking permission metadata because attributes are concrete-class only. Surfaces as "nobody can access this screen," which is noisy and therefore safer, but it will arrive as an incident if our hierarchy is deep.
  • Panel-scope inconsistency — roles scoped one way and permissions another, causing permission UI to display entries that sync commands do not manage, or protected-role assignment to reference a role the UI hides. The five layers that must change together make this the most likely operational mistake, not a package defect.
  • Shared-owner misconfiguration — duplicate visible tabs or duplicate sync rows reappearing when a shared owner is also opted in or when getSharedPermissionOwner() points at an opted-out class.
  • Protected-role bypass misuse — Gate::before() granting more than intended because it was enabled without reviewing its blast radius.
  • Supply-chain compromise — materially mitigated by SHA pinning and dependency cooldowns, but never zero; this is the one failure mode where the package's own controls are the primary defense.
  • Upgrade-wall stall — a Laravel 13 upgrade blocked on this package's compatibility, discovered late because the package was never on the upgrade critical path.

Ramp-up. Modest for anyone fluent in Filament and Laravel authorization, with one non-obvious learning curve: the mental model shift to treating the Filament owner as the permission subject. That reframing is what makes the traits, the shared-owner semantics, and the panel-scope configuration coherent, and it is not the mental model most Laravel developers arrive with. I would budget a half-day of reading (AGENTS.md first, then policies, then the built-in resource) plus the pilot spike in Integration step 2–4, and expect one engineer to own the whole surface — policies, sync, panel scope, protected role — rather than distributing it, precisely because the five-layer consistency requirement means partial ownership is how inconsistencies get introduced. The bundled Boost skills are a genuine ramp-up accelerant for teams already doing agent-assisted Laravel work and a non-event for teams that are not.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console