arcanedev/laravel-policies
A lightweight Laravel package for working with authorization policies. It provides helpers to register, resolve, and organize policy classes, making it easier to map models to policies and keep access-control logic consistent across your application.
Verdict: do not adopt as a dependency; vendor the pattern if the ergonomics are wanted.
Architecture fit. The package is a thin registration layer over Laravel's native authorization stack — a service provider plus an attribute/annotation class that maps controller actions to policy classes and hands them to Illuminate\Auth\Access\Gate. It introduces no persistence, no HTTP surface, no queue workers, no external services, and no new runtime. That is architecturally ideal: it is additive, reversible, and does not fork the framework's auth flow. Policies still resolve through Gate, so the blast radius of removal is a service provider and a handful of attributes.
Integration feasibility. MIT-licensed, Composer-installable, small public surface. The blocker is chronology, not complexity: last release December 2020 places it in the Laravel 7/8 + PHP 8.0 era. Laravel 8 also shipped native policy auto-discovery (Post → PostPolicy by convention) and authorizeResource(), which together cover the large majority of what this package was built to solve. The differentiator is only controller-action-level attribute mapping — a genuinely narrow slice.
Technical risk.
| Risk | Likelihood | Impact |
|---|---|---|
| Abandoned upstream (no fixes, no security triage) | Certain | Medium |
| Incompatible with Laravel 10/11 / PHP 8.2+ | High | Blocker |
| Fail-open authorization (attribute resolves to nothing) | Medium | Severe |
| Conflict/confusion with native policy discovery | High | Low–Medium |
| No adoption canary (2 stars, 0 dependents) | Certain | Medium |
The 2-star / 0-dependent profile is the decisive signal. The 10.41 opportunity score reflects an unserved niche, not an undervalued asset — nobody has validated this code path in production. With MIT licensing, forking is legally trivial, which further weakens the case for consuming it as a third-party dependency.
Key questions to answer before any code is written:
composer.json constraints, and does the provider boot on our target Laravel version? (1-day spike, hard gate.)Gate::guessPolicyNamesUsing / native discovery — and which wins on conflict?$policies array for incremental adoption, or is it all-or-nothing?Stack fit. Realistically Laravel 8 / PHP 8.0. On Laravel 10 or 11 the package will almost certainly fail resolution or boot. Confirm the constraint ceiling in the spike; if it caps below our version, the dependency path is closed and only the fork path remains.
Migration path. Do not migrate existing AuthServiceProvider::$policies arrays. They work, they are documented, and they are understood by every Laravel developer we hire. Migration would be pure churn with no functional gain and would concentrate authorization risk in a single rewrite. The only defensible scope is a greenfield bounded module where the attribute style is a stated preference.
Compatibility. Two overlap hazards need explicit handling. First, authorizeResource() in controllers already performs per-action policy checks; layering attribute-based mapping on top risks double authorization and divergent rules between the two mechanisms. Second, native convention-based discovery may already resolve a policy the attribute also declares — pick one authority per module and document it, or debugging becomes guesswork.
Sequencing.
App\Support\Authorization under our namespace.Estimated effort: 1–2 days to spike, 3–5 days to fork with CI and a test harness, one sprint to pilot.
Maintenance. Adopting this package converts a dependency into an implicit fork. Budget 2–5 engineer-days per year as a baseline floor, with a multi-day spike at every Laravel major upgrade as framework internals around policy resolution evolve. Those costs are identical whether we consume the package or vendor it — which is precisely why vendoring wins: we pay the maintenance either way and get control in exchange.
Support. There is no upstream. No issue triage, no security response, no compatibility patches. We need an internal owner named in the ADR and a runbook entry describing how authorization is wired and how to unwind it.
Scaling. A non-issue. The work happens once at container boot; there is no per-request overhead beyond an array lookup, no external calls, no state. It will not be the constraint at any realistic application size. Performance is not part of this decision.
Failure modes. Ranked by severity:
Ramp-up. A mid-level Laravel developer absorbs the API in an hour or two — it is a small surface. The real cost is divergence from the documented framework idiom: every new hire, every code review, and every Stack Overflow search will assume $policies and authorizeResource(). That ongoing cognitive tax is the strongest argument against adopting a convenience layer whose remaining value over native discovery is one narrow feature.
How can I help you explore Laravel packages today?