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.
composer require arcanedev/laravel-policies then open vendor/arcanedev/laravel-policies/src/. With 2 stars, one release (2020-12-01), and zero dependents, the source is the documentation — budget 15 minutes to read the manager class and service provider before writing any application code.extra.laravel.providers in composer.json, so the service provider should register itself. Verify with php artisan about (Laravel 9+) or by dumping app()->getLoadedProviders(). If it is not discovered, add the provider manually to config/app.php.config/policies.php in the package or a publishes() call in the provider: php artisan vendor:publish --provider="Arcanedev\LaravelPolicies\Providers\LaravelPoliciesServiceProvider". The provider's boot()/register() will tell you the exact namespace and tag.App\Models\Foo → App\Policies\FooPolicy). Before adopting this package, confirm it solves a problem native discovery doesn't — typically centralised, non-conventional registration or policy grouping.Models/Policies naming convention. That is the smallest end-to-end test of whether the package earns its place.Centralised registration in a service provider. The core value of a "policies manager" is moving policy-to-model mapping out of scattered Gate::policy() calls into one place. Keep it in a dedicated AuthServiceProvider (or the package's own registration hook) so the mapping is greppable:
// app/Providers/AuthServiceProvider.php
public function boot(): void
{
// Shape depends on the package API — verify method names in src/
$this->app['arcanedev.policies']->register(Post::class, PostPolicy::class);
}
Group registration for domain modules. If the manager exposes a bulk/array-based registration method, use it to register a whole bounded context (e.g. all Billing models) in one call. This is the pattern that actually justifies the dependency over vanilla Gate::policy().
Keep policies framework-idiomatic. Write policies as normal Laravel policies (viewAny, create, update, delete, plus before() for super-admins). The package should be registering them, not replacing Gate — you still call $this->authorize(), Gate::allows(), and @can exactly as before.
Inspect via the Gate, not the manager. In controllers, form requests, Blade, and API resources, resolve authorization through Gate/authorize() so that swapping the manager out later is a one-file change.
Testing. Policies should be tested directly rather than through HTTP:
$policy = Gate::getPolicyFor(Post::class);
$this->assertTrue($policy->update($user, $post));
For feature tests, $this->actingAs($user)->get(...) exercises the full registration path and is the fastest way to catch a mis-registered mapping.
Integration tip: if you use a modular/multi-tenant structure, register the manager's mappings in each module's service provider rather than one monolithic AuthServiceProvider — this keeps the package's centralised registry useful without creating a merge-conflict hotspot.
Gate and Illuminate\Contracts\Auth\Access\Gate::getPolicyFor(). Run composer update and your test suite on your target framework version before committing to the package.Gate::getPolicyFor(Post::class) (did it resolve?) → Gate::abilities() (is the ability registered?) → dump(Gate::forUser($user)->inspect('update', $post)) (Laravel 9.17+, gives the exact reason). If getPolicyFor() returns null, the manager registration never ran — check provider load order.php artisan config:cache will bake in the published config. Any dynamic/tenant-aware policy registration must happen in a provider's boot(), not in a config file, or it will break in production after caching.register() time and your own provider registers policies in boot(), make sure your provider is listed after the package provider in config/app.php (or that package discovery runs first). Mis-ordering produces silently-empty registries.app/Support/ is a legitimate, low-risk hedge against abandonment.How can I help you explore Laravel packages today?