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

elpandape/filament-permission

elpandape/filament-permission is a Filament plugin for managing roles and permissions in Laravel admin panels. It provides UI resources for creating roles, assigning permissions, and controlling access to Filament resources and pages, helping teams implement authorization quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the package, publish its config and migrations, and run migrations before assigning any roles. The privileged role is a first-class concept, not just another seeded role—treat it as bootstrap infrastructure.
  • Look first at:
    • the config entry naming the privileged role and the grants.unrestricted setting;
    • the PrivilegedRole class, especially the new isLastHolder() helper;
    • the policy/gate that authorizes granting and revoking roles;
    • any relation manager or admin UI integration that attaches/detaches roles.
  • Bootstrap the first holder from the command line (seeder, tinker, or a dedicated artisan command). The UI intentionally will not let a non-holder grant the privileged role, so a fresh install has no in-panel path to create its first super admin.
  • First day-to-day use case: sign in as the bootstrapped holder, hand the privileged role to a second trusted account, then continue using normal role management for everyone else. Keep the CLI path documented as the break-glass route.

Implementation Patterns

  • Bootstrap and handover: Create the first holder outside the panel. For handover, the current holder grants the privileged role to the successor first, verifies access, and only then removes it from themselves. The package permits the removal because another holder exists; it blocks removal of the last holder.
  • Mirror the authorization rule in custom UI: Any custom attach/detach action, bulk action, or API endpoint should ask the same question the package asks: could this actor have granted this role in the first place? Do not rely on a generic “manage roles” permission alone. The v1.10.0 change makes detachment follow grant authority, so a panel editor should no longer be able to strip roles that reach further than their own.
  • Guard last-holder removal: Call PrivilegedRole::isLastHolder() before rendering detach controls and again inside the detach handler. Use it to disable buttons, filter bulk selections, and short-circuit API requests. Keep the server-side check even when the UI hides the action.
  • Treat the privileged role as role-based, not permission-based: The guard checks the role itself, so grants.unrestricted does not bypass it. If you build custom “super admin” checks, check role membership or the package’s helper—not an unrestricted-permissions flag.
  • Integrate with relation managers deliberately: If you use a Filament-style relation manager, override canDetach, bulk detach visibility, and any “detach any” behavior. The default relation manager behavior may still offer broader detach options than the package’s grant/revoke rules; align them explicitly.
  • Testing pattern: Cover four actors—non-holder, holder, last holder, and non-last holder. Assert that a non-holder cannot grant the privileged role, a holder can hand it over, a holder can remove a non-privileged role they could have granted, and nobody can remove the privileged role from its last holder.
  • Recovery workflow: Document a CLI recovery path for the “no holder left” scenario. Even though v1.10.0 prevents it through the package, direct database edits, imports, or custom code can still create that state.

Gotchas and Tips

  • Empty privileged role set blocks handover: If the last holder is removed through a path that bypasses the guard, no one can hand the role out from the panel. Recovery is command-line only. Keep a runbook and restrict direct database access.
  • Grant-before-revoke: Removing the privileged role from the current holder before granting it to the successor will be blocked when they are the last holder. Perform handover in the correct order.
  • grants.unrestricted is not a super-admin bypass: It may widen what a role can grant, but it does not satisfy the privileged-role check. Do not use it as a proxy for “can manage super admins.”
  • Check-then-act races: isLastHolder() can become stale between rendering and submission. Re-check inside a transaction and, where possible, lock the relevant role assignments before detaching. Two concurrent removals of the last two holders are the dangerous case.
  • Cache invalidation after handover: Role and permission caches can leave the new holder without access or the old holder with stale access. Clear the relevant caches after granting or revoking the privileged role, and verify with a fresh session.
  • Relation manager mismatch: The release notes call out that the relation manager previously offered to detach anything except the privileged role. Audit custom relation managers and bulk actions for the same overreach; the package’s core rule is now stricter than a naive “detach anything” UI.
  • UI hiding is not authorization: Disabling a detach button improves UX but does not enforce the rule. Keep policy checks and isLastHolder() checks in the request path.
  • Extension points: Prefer extending the package’s policy/gate and role model over duplicating the rules. If you customize the privileged role name or the grant authority logic, keep a single shared ability such as canGrantRole and reuse it for both attach and detach decisions.
  • Debugging: Log the actor, target user, role, and the result of the grant-authority and last-holder checks on every privileged-role mutation. Most confusing failures here are authorization mismatches between the UI and the policy, not database errors.
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.
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
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource