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

Laravel Permission Manager Laravel Package

hosseinhezami/laravel-permission-manager

Enterprise-grade Laravel permission manager combining RBAC, ABAC, role hierarchy, multi-tenancy, wildcard and temporary permissions, condition engine, multi-guard support, audit logging, middleware DSL, Blade directives, and Gate/Policy integration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Idiomatic Laravel integration: service provider, publishable config/migrations, a PermissionTrait on the User model, middleware aliases (pm:permission:*), Blade directives, and Gate::before() hooks. Nothing here fights the framework; it extends the native authorization pipeline rather than replacing it.
  • The feature surface is deliberately broader than Spatie: RBAC + ABAC condition engine + role hierarchy + multi-tenancy + audit. For a product that genuinely needs contextual (attribute-based) decisions — "can edit this post because they own it and it's a draft" — this collapses 2–3 bespoke subsystems into one dependency.
  • Schema footprint is the main architectural cost: 14 tables (roles, permissions, permission_groups, permission_sets, role_permissions, role_inherits, user_roles, user_permissions, teams, team_user, permission_conditions, permission_audits, authorization_logs). That is a meaningful commitment of our database namespace and migration graph versus Spatie's ~5 tables.
  • The teams + pm.team middleware is opinionated tenancy: it wants to own tenant context resolution (e.g., X-Team-Id header). That will collide with any existing tenancy layer (stancl/tenancy, Spatie multitenancy, or a homegrown tenant_id global scope). This is the single largest architectural integration question.

Integration feasibility

  • Install path is well-documented and short: composer require → publish config → publish migrations → migrate → add trait. There is also a permission-manager:install --migrate convenience command. A competent Laravel engineer can have a green path in under a day.
  • Prebuilt accelerators reduce build cost: permission:sync-routes (generate permissions from the route table), resource generator (CRUD permissions per model), import/export (JSON/CSV/YAML), and diagnostic CLI (permission:doctor, permission:why, permission:tree). The explain() API and permission:why are disproportionately valuable for support load — authorization bugs are otherwise expensive to triage.
  • Migration off the package is undocumented. Once 14 tables hold our authorization truth, swapping engines becomes an ETL project. Acceptable only if we treat authorization as an internal, wrapped concern.

Technical risk

  • Maturity / bus factor — highest risk. 62 stars, 0 dependents, single maintainer, no docs site, no commercial backing, no evidence of external production use. Maturity signals are limited to "readme, releases." A composite score of ~17.6 with a 6.82 opportunity score reads as "interesting capability, unproven adoption."
  • Release recency is anomalous. The last release is stamped 2026-08-21 — a future date. Either a data-pipeline artifact or a versioning/metadata irregularity; verify against Packagist directly before treating release cadence as a health signal.
  • Test evidence is weaker than it looks. "141 passing / 226 assertions" is a reasonable suite, but the README presents assertion count as a coverage badge. No published coverage percentage, no PHPStan/Psalm level, no CI matrix visible in the provided sources.
  • Precedence complexity. A seven-tier resolution order (super-admin → user deny → role deny → user allow → role allow → inherited → default deny) combined with wildcards and negation (!users.delete) is powerful and easy to misconfigure. Misconfiguration here is a security defect, not a UX defect. explain() mitigates, but requires discipline.
  • Wildcard over-grant. * and users.* are one keystroke from privilege escalation. Needs policy, review gates, and CI linting on seeded permission definitions.
  • Custom condition DSL. JSON-based, explicitly no eval() — good. But it is a bespoke DSL we will be authoring, reviewing, and debugging without a formal spec beyond the README.
  • Cache dependency. Tagged cache with hierarchical invalidation implies Redis/Memcached. On file or database cache drivers, correctness degrades to staleness.
  • Laravel 13 support claim is forward-looking and cannot be validated against a shipping framework release.

Key questions

  • Is there a security disclosure policy and a documented semver/backwards-compatibility contract?
  • Which databases are actually tested (MySQL/PostgreSQL/SQLite)? Any JSON-column assumptions for the condition engine?
  • Does the condition engine evaluate in PHP or push predicates into SQL? What is the query count for a role-hierarchy check at 5 roles deep?
  • How does team context interact with global scopes and queued jobs (no HTTP request → no X-Team-Id header)?
  • Is there a documented Spatie laravel-permission importer, or must we write the ETL?
  • Audit log retention, PII exposure, and whether authorization_logs (per-access-attempt logging) is on by default.
  • Any published benchmarks for permission checks per request at 10k+ users?

Integration Approach

Stack fit

  • Target: Laravel 10–12, PHP 8.1+, Eloquent, standard service-container auth. Fits a modular monolith or a multi-tenant SaaS backend cleanly. Poorer fit for a microservice fleet where each service would need its own 14-table install, or for a system already standardized on Spatie.
  • Explicit non-fits: apps where Filament or another package has already claimed the authorization layer (Filament's panels assume Spatie semantics); apps under a tenancy framework that already owns tenant resolution; regulated environments requiring vendor support SLAs.

Migration path

  • Greenfield (recommended): adopt directly at project inception, before roles are seeded anywhere. Lowest cost, highest leverage — the multi-tenancy and ABAC features are effectively free if there is no incumbent.
  • Brownfield from Spatie: no documented importer. Budget an ETL for role/permission/user-role mappings, plus a reconciliation period. The table shapes differ enough that this is a real, estimate-worthy work item — not a script.
  • Brownfield with custom authorization: wrap first. Introduce an internal AuthorizationService interface that today delegates to existing code and tomorrow delegates to this package. This makes the dependency reversible and is the single best risk mitigation available, given the maturity profile.
  • Vendor-and-fork contingency: MIT license means forking is legally clean. Plan to pin to an exact version (composer require hosseinhezami/laravel-permission-manager:1.x.x) and keep a fork-ready posture.

Compatibility

  • Multi-guard support (web, api, admin isolation) is a genuine differentiator and matches how most apps actually separate staff and customer surfaces.
  • Gate::before() registration is a shared global — confirm no other package or AuthServiceProvider block registers one, or ordering will silently change authorization outcomes.
  • Team middleware vs. existing tenancy: decide explicitly whether this package owns tenant context or defers to ours. Do not run both.
  • Queue/console context: team-scoped permission checks must not be evaluated in jobs without an explicitly bound team context, or checks will either fail closed (annoying) or resolve to the wrong tenant (dangerous).

Sequencing

  1. Spike (1–2 weeks): install in a throwaway branch; model our three most complex real authorization rules (one hierarchical, one ABAC/ownership, one tenant-scoped); measure query counts and confirm cache-tag behavior on our actual cache driver.
  2. Wrap: define the internal AuthorizationService boundary; forbid direct facade/trait use outside it.
  3. Pilot: one bounded module, one team, feature-flagged. Instrument denial rates and explain() usage.
  4. Baseline rollout: migrate core RBAC + middleware; defer wildcards until policy is written.
  5. ABAC + conditions: only after baseline is stable and the team is fluent.
  6. Audit logging: enable last, with an explicit retention policy and a decision on whether per-access-attempt logging is on.
  7. Multi-tenancy: enable only if we are not already tenanted; migrate one tenant at a time.

Operational Impact

Maintenance

  • Effectively single-maintainer. No foundation, no corporate sponsor, no visible contributor base. Assume upgrades may lag Laravel releases and that we may need to carry patches.
  • Recommend: version pinning, a composer.lock diff review in CI, a quarterly upstream-health check (open issues, time-to-merge, release cadence validated against Packagist), and a pre-agreed trigger for forking (e.g., two missed Laravel compatibility windows).
  • The 14-table schema is our migration burden on every Laravel major upgrade. Add it to the upgrade checklist explicitly.

Support

  • Community-only via GitHub issues. No SLA, no paid tier, no professional services. Our own platform team becomes tier-1 and tier-2 support for authorization defects.
  • The diagnostic surface is the compensating control: permission:why, permission:doctor, permission:tree, PermissionSnapshot, and explain() should be documented in our internal runbook before rollout. These convert "user says they can't see the button" from an hour of code archaeology into a one-command answer.
  • Escalation ceiling: if a security-relevant defect lands upstream with no response, our only path is the fork.

Scaling

  • Authorization checks run on essentially every request. The tagged-cache layer with hierarchical invalidation is the performance keystone — Redis is effectively mandatory, not optional.
  • Role-hierarchy traversal plus wildcard matching plus ABAC condition evaluation is more work per check than flat RBAC. Benchmark before broad rollout and cache aggressively per (user, permission, tenant) tuple.
  • authorization_logs (optional access-attempt logging) introduces write amplification on the hottest path. Default it off; enable only for targeted debugging or compliance windows with sampling.
  • Audit tables grow unboundedly. Define partitioning/retention and archival from day one — this is a scheduled job someone must own.

Failure modes

Failure Impact Mitigation
Cache driver lacks tag support Stale or over-permissive grants Enforce Redis; add a boot-time assertion
Wildcard * or users.* mis-seeded Silent privilege escalation Lint seeded permissions in CI; ban * outside super-admin
Deny/allow precedence misunderstood Users see or lose access unexpectedly explain() in support tooling; test matrix per precedence tier
Cyclic role inheritance Runtime exception on check Catch in seeding; assert hierarchy is a DAG at deploy
Missing team context in jobs/console Cross-tenant leakage or false denials Require explicit tenant binding; fail closed
Gate::before() conflict with existing package Authorization silently altered Audit all Gate::before registrations before install
Abandoned upstream / no Laravel-N support Blocked framework upgrade Fork plan + version pin + quarterly health review
Unbounded audit tables Query and storage degradation Retention policy, partitioning, archival job

Ramp-up

  • Moderate. The RBAC + middleware + Blade surface is a day for a Laravel-fluent engineer. The ABAC condition DSL, the seven-tier precedence order, and the tenancy semantics are the real learning curve — budget a week of guided practice plus a written internal decision guide ("when to use a role vs. a direct permission vs. a condition").
  • Team-fluency dependency: the blast radius of a mistake is security, not styling. Recommend a designated owner (one engineer accountable for the authorization model) rather than diffuse ownership, plus a review requirement on any change touching seeding, wildcards, or conditions.

TPM recommendation

Conditional adopt. The capability set is genuinely differentiated — ABAC plus multi-tenancy plus hierarchy plus explain() is a real gap in the Laravel ecosystem — and the integration cost is low. But 62 stars and zero dependents mean we are the first production user, and the support model is "we are the support model."

Approve for a greenfield, multi-tenant Laravel product where ABAC is a stated requirement, behind the AuthorizationService wrapper, in a 6–8 week time-boxed pilot with go/no-go gates on: upstream responsiveness, measured check latency under our cache driver, and our team's ability to author conditions without escalation. Decline for brownfield systems already working on Spatie, and hard-decline for any context where an authorization defect requires a vendor SLA.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings