PHPackages                             brighterly/laravel-dynamic-policies - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. brighterly/laravel-dynamic-policies

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

brighterly/laravel-dynamic-policies
===================================

Namespace-scoped Laravel policies per route group via setPolicies() macro

v1.0.1(1mo ago)02.7k↑48.4%MITPHPPHP ^8.3

Since Mar 19Pushed 1mo agoCompare

[ Source](https://github.com/brighterly/lib-laravel-dynamic-policies)[ Packagist](https://packagist.org/packages/brighterly/laravel-dynamic-policies)[ RSS](/packages/brighterly-laravel-dynamic-policies/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (4)Versions (4)Used By (0)

brighterly/laravel-dynamic-policies
===================================

[](#brighterlylaravel-dynamic-policies)

Namespace-scoped Laravel policies per route group via a `setPolicies()` macro.

Laravel's default policy auto-discovery is global — one policy class per model across the whole app. This package lets you register **different policies for the same model depending on which route group the request belongs to**, using a simple fluent macro.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11 or 12

Installation
------------

[](#installation)

```
composer require brighterly/laravel-dynamic-policies
```

The service provider is auto-discovered via Laravel's package auto-discovery.

Usage
-----

[](#usage)

### 1. Define a `PoliciesMap` for each namespace

[](#1-define-a-policiesmap-for-each-namespace)

Create an interface (or class) implementing `Brighterly\LaravelPolicies\Contracts\PoliciesMap` and declare the `POLICIES_MAPPING` constant:

```
// app/Policies/Tutor/TutorPoliciesMap.php
namespace App\Policies\Tutor;

use App\Models\Booking;
use App\Models\TutorTask;
use Brighterly\LaravelPolicies\Contracts\PoliciesMap;

final class TutorPoliciesMap implements PoliciesMap
{
    public const array POLICIES_MAPPING = [
        Booking::class  => BookingPolicy::class,
        TutorTask::class => TutorTaskPolicy::class,
    ];
}
```

```
// app/Policies/Customer/CustomerPoliciesMap.php
namespace App\Policies\Customer;

use App\Models\Booking;
use Brighterly\LaravelPolicies\Contracts\PoliciesMap;

final class CustomerPoliciesMap implements PoliciesMap
{
    public const array POLICIES_MAPPING = [
        Booking::class => BookingPolicy::class,
    ];
}
```

Both maps register a policy for `Booking` — but a different one per namespace.

### 2. Attach the map to a route group

[](#2-attach-the-map-to-a-route-group)

Call `->setPolicies()` before `->group()` in your `RouteServiceProvider`:

```
use App\Policies\Customer\CustomerPoliciesMap;
use App\Policies\Tutor\TutorPoliciesMap;

Route::prefix('tutor')
    ->setPolicies(TutorPoliciesMap::POLICIES_MAPPING)
    ->group(base_path('routes/tutor.php'));

Route::prefix('cs')
    ->middleware('api')
    ->setPolicies(CustomerPoliciesMap::POLICIES_MAPPING)
    ->group(base_path('routes/customer_api.php'));
```

The macro works on both `Route` (fluent route builder) and `RouteRegistrar` (the object returned when you chain attributes like `->prefix()`, `->middleware()`, etc.).

### 3. Authorize as usual

[](#3-authorize-as-usual)

Nothing changes in controllers or policies — use Laravel's standard authorization:

```
// in a controller
$this->authorize('update', $booking);

// or via Gate
Gate::authorize('view', $booking);

// or in Blade
@can('update', $booking)
```

The correct policy class is resolved based on which route group handled the request.

PhpStorm plugin
---------------

[](#phpstorm-plugin)

For the best experience you can use this plugin [Custom Policy Navigator PhpStorm plugin](https://plugins.jetbrains.com/plugin/30763-laravel-custom-policy-navigator)

How it works
------------

[](#how-it-works)

`setPolicies()` attaches the `SetCustomPolicy` middleware to the route group, encoding the `[Model::class => Policy::class]` pairs as middleware parameters. When a request hits a route in the group, the middleware calls `Gate::policy($model, $policy)` for each pair — overriding Laravel's global policy registry for that request only.

Optional: shared `PoliciesMap` contract in your app
---------------------------------------------------

[](#optional-shared-policiesmap-contract-in-your-app)

If you want a shared base interface at `App\Policies\Contracts\PoliciesMap` (required by the [Custom Policy Navigator PhpStorm plugin](https://github.com/brighterly/tools-laravel-policies-plugin)), publish the stub:

```
php artisan vendor:publish --tag=laravel-policies-stub
```

This creates `app/Policies/Contracts/PoliciesMap.php` extending the package interface. Your maps then implement `App\Policies\Contracts\PoliciesMap` instead of the package interface directly.

Local development
-----------------

[](#local-development)

To use the package from a local path (e.g. alongside the app in a monorepo), add a path repository to `composer.json`:

```
"repositories": [
    {
        "name": "laravel-policies",
        "type": "path",
        "url": "../tools-laravel-policies-lib",
        "options": { "symlink": false }
    }
]
```

> Use `"symlink": false` when the app runs inside Docker — symlinks to host paths are not accessible inside the container. After each change to the library, run `composer update brighterly/laravel-policies` inside the container.

License
-------

[](#license)

MIT

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance90

Actively maintained with recent releases

Popularity22

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~48 days

Total

2

Last Release

51d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ff0892ece8226f938f067b4813e0aabfd2a8a2c99c051467cab9efa9c939c51a?d=identicon)[Brighterly](/maintainers/Brighterly)

---

Top Contributors

[![MDG11](https://avatars.githubusercontent.com/u/59790837?v=4)](https://github.com/MDG11 "MDG11 (3 commits)")[![Vladislavow](https://avatars.githubusercontent.com/u/57527056?v=4)](https://github.com/Vladislavow "Vladislavow (3 commits)")

### Embed Badge

![Health badge](/badges/brighterly-laravel-dynamic-policies/health.svg)

```
[![Health](https://phpackages.com/badges/brighterly-laravel-dynamic-policies/health.svg)](https://phpackages.com/packages/brighterly-laravel-dynamic-policies)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76518.2M120](/packages/laravel-mcp)[hasinhayder/tyro-dashboard

Tyro Dashboard - Beautiful admin dashboard for managing Tyro roles, privileges, users, and settings

5452.7k](/packages/hasinhayder-tyro-dashboard)[laravel/surveyor

Static analysis tool for Laravel applications.

8690.3k12](/packages/laravel-surveyor)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[laragear/turnstile

Use Cloudflare's no-CAPTCHA with HTTP/3 in your Laravel application.

697.1k](/packages/laragear-turnstile)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
