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 Warden Laravel Package

elpandape/filament-warden

Filament Warden adds role and permission management to Filament admin panels. Define roles, assign abilities, and gate access to resources, pages, and actions through a clean, configurable interface. Built for Laravel, it keeps authorization simple and consistent across your whole panel.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Filament-facing roles/permissions UI built on top of elpandape/warden. The screens you get are the permission grid, an account's roles, and a role's inheritance; the package requires warden ^3.2 as of 3.5.0, so check composer show elpandape/warden before anything else — the README previously lied about this constraint, so verify in composer.lock rather than trusting the docs you remember.

Minimal path:

  1. composer require the package and let it pull elpandape/warden ^3.2.
  2. Publish and run the migrations, then publish the config.
  3. If you are coming from warden 3.0.0, run php artisan warden:clean --stranded once before letting anyone touch the grid. This is the documented upgrade step to 3.5 and it also sweeps the ghost grants described in Gotchas.
  4. Seed your first super-admin role and assign it directly to your user (the account roles screen is read/write, so you need one working login before the UI is usable).

First use case: open the permission grid for a role, tick a cell, save. That single click is now one warden operation — every event dispatched during the save carries the same $operation. That is the hook to build against first, because it is what makes an audit trail legible.

Implementation Patterns

Group your audit log by $operation, not by event. Before 3.5 you had to correlate events by timestamp and actor; now EditRole::save(), CreateRole::create(), a flip/removal of a direct grant, an account-role save, and an inheritance save each stamp all their events with one $operation. A listener that appends to audit_entries keyed on $operation reads a grid save as the one act it was, instead of fifteen row-level diffs.

Custom screens must adopt the operation themselves. If you have written your own Filament page wrapping role editing (rather than subclassing EditRole/CreateRole), you are outside the guarantee. Wrap your save in a warden operation so downstream listeners still see one act. Do this before shipping any audit feature — retrofitting correlation logic onto flat events is miserable.

Do not assume atomicity. The release notes are explicit: "an operation opens no transaction and holds nothing back." An operation is a correlation ID, not a unit of work. If your save touches the role, its grants, and a side table, wrap it in DB::transaction() yourself. The only place you get rollback for free is the grid's own refusal path (see Gotchas).

Listen for RoleRetracted. Since warden 3.1, deleting a role dispatches RoleRetracted per holder. Use that for the things a delete should trigger — cache busting, notifying the affected users, writing the audit line — rather than querying for orphaned assignments after the fact. The package's own delete-confirmation copy was corrected in 3.5 to stop claiming the assignments vanish "with no trace", because they don't.

Prefer the shipped screens over a fork. The grid, account-roles and inheritance pages share a nestedRoles() contract and a set of delete/rename rules; reimplementing one of them means reimplementing the trash-aware refusal logic in 3.5, which is subtle enough that the package got it wrong once.

Testing pattern: assert one operation per save by capturing events in a listener and asserting count(array_unique($operations)) === 1. That test will catch a regression where a save silently splits into two operations far earlier than a UI test would.

Gotchas and Tips

A grid save can now fail where it used to "succeed". With a swapped permission model using SoftDeletes, warden 3.2 refuses to recreate a narrowed rule whose twin sits in its trash — and it refuses after the unconditional grant is written. 3.4 swallowed that refusal, kept the grant, and reported success while the cell rendered as every row. 3.5 fails the save and rolls back. Correct behaviour, but if you have a swapped model with SoftDeletes, expect saves that previously reported green to start erroring. Such a model still isn't supported; this just stops it lying to you.

TrashedCatalogRow as an error page is a known gap, not a bug you introduced. Granting from the grid a permission whose plain row is in the trash still ends in that exception, uncaught, as an error page. If you can delete permissions in your app, either guard the grid against trashed rows or accept the page. Also: a role or permission model with SoftDeletes is explicitly out of scope.

Ghost grants. A grant with an authority type and no key still counts as everyone on the permissions screen — in holders, in the delete rule, in the rename lock — even though warden has read such a row as nobody's since 3.0.1. The UI and the backend disagree until warden:clean --stranded deletes the row. Run it as part of your upgrade and periodically thereafter; otherwise a "who has this permission" panel is quietly wrong.

Re-sync overridden translations. The role-delete warning was reworded in both languages in 3.5. If you published and edited the lang files to customise that copy, you are now carrying the false "no trace afterwards" claim and will not get the fix.

Debugging operation boundaries: if two events from one save land under different $operation values, the save escaped the package's screen — a custom action, an observer, or an afterSave hook dispatching separately. That is the first thing to check when an audit entry looks split.

Still open from 3.4.0, so don't spend time reporting them: the inspector's live region, overridden stylesheet rules, the pending review's date comparison, and two strict role-key comparisons. Work around them rather than patching the vendor tree.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource