amir/laravel-permission
Role and permission management for Laravel apps, with migrations, middleware, Blade directives, and Eloquent traits for assigning roles and abilities to users.
Architecture fit
The package targets the standard Laravel authorization surface: an Eloquent trait on the User model, published migrations for roles/permissions/pivot tables, service-provider auto-discovery, and binding into Laravel's Gate so can()/@can keep working. That means it can slot in without changing controller-level authorization idioms, which is the main thing a TPM should care about — the blast radius is the data model and the seeding path, not the application code.
The naming is the first thing to flag. amir/laravel-permission is one character away from spatie/laravel-permission, the de facto standard with a five-figure star count and thousands of dependents. Any engineer reading a ticket, a README, or a Stack Overflow answer will assume Spatie semantics. Treat the two as incompatible mental models until proven otherwise, and expect to spend review time correcting assumptions rather than code.
Integration feasibility
Mechanically trivial: composer require, publish config and migrations, add the trait, run migrations, seed roles. A competent Laravel engineer can produce a working spike in under a day. The real feasibility question is not "can we install it" but "can we staff it" — 47 stars and zero dependents means there is no public corpus of production war stories, no third-party tutorials, no ecosystem of companion packages (admin UIs, Nova/Filament integrations, tenant-aware extensions). Every edge case becomes a first-principles investigation.
Technical risk
composer.json and review every lockfile diff.can() call determines whether it is viable at all under load. This is the single most important thing to verify empirically.composer.json constraints against our actual Laravel and PHP versions; a package last released December 2024 may not yet declare support for the newest major.Key questions
spatie/laravel-permission if both are ever installed?Stack fit Assume a conventional Laravel monolith or modular monolith on PHP 8.x. Fit is good for a single-tenant app with a simple role → permission → user model and a small number of guarded resources. Fit degrades quickly for multi-tenant SaaS, per-object/record-level permissions, or anything needing delegation, approval workflows, or policy composition — those are exactly the areas where an unproven package forces you to write the missing layer yourself, at which point the package is contributing migrations and not much else.
Migration path
If we are already on Spatie, do not migrate. The API shapes look similar enough to be dangerous — same trait name, same hasRole/can vocabulary, different table names, different caching semantics, different pivot columns. A migration is a schema rewrite plus an audit of every gate, policy, Blade directive, and seeder, with a silent-failure risk: a check that used to pass returns false and the UI simply hides a button. That is a bug class that survives QA.
If we are greenfield or on hand-rolled is_admin flags, migration is genuinely cheap — one sprint-internal task, no data of consequence to transform.
Compatibility Verify three things before committing: declared Laravel/PHP ranges, whether the migrations collide with existing tables of the same name (they will if a prior Spatie install was ever present), and whether the service provider registers cleanly under Octane or in a queued-job context where the auth user may be absent.
Sequencing
can() path with a representative permission count (say 200 permissions, 50 roles). Produce a query-count and latency number.composer audit step to CI.Maintenance Budget for fork maintenance, not for "using a package." The realistic steady state is: we own a vendored copy and rebase rarely. Assign a named owner. The cost is low but non-zero, and it must be visible in planning or it becomes nobody's job until a Laravel major upgrade breaks it.
Support No commercial support, no SLA, no guaranteed response on issues. Internal engineers are the support tier. Documentation quality is unknown and likely thin; assume the source is the documentation. This is acceptable for a small internal tool and unacceptable for a system with an external audit or compliance obligation attached to its access control.
Scaling Two axes. Data volume: role/permission tables are small and stable, so row growth is a non-issue. Check volume: authorization runs on nearly every request, so caching behavior dominates. If the package queries per check, p99 latency will degrade as permission count grows and can push you into a cache layer you build and own anyway. Multi-tenancy is the other cliff — retrofitting tenant scoping onto a global-role model means a schema change plus a full audit of every gate.
Failure modes
can() to return false, the UI hides a control, and no error is raised. Instrument authorization denials and alert on anomaly, or this is invisible until a customer reports a missing button.Ramp-up For an engineer who knows Laravel authorization, a day. For an engineer who knows Spatie, add a day of unlearning — this is the hidden cost and the one most likely to produce a subtle bug, because the surface vocabulary is identical while the semantics are not. Onboarding documentation must be internal, written by us, and must include the explicit "this is not Spatie" warning at the top.
Recommendation. A TPM should not standardize on this package. The 47 stars and zero dependents are not a maturity signal to be overcome by due diligence; they are the due diligence result. Permit it only for a bounded internal tool where a fork is an acceptable endgame, and only after the spike returns concrete performance numbers. For anything on the revenue path or under audit, take the boring option and reallocate the risk budget elsewhere.
How can I help you explore Laravel packages today?