PHPackages                             dynamik-dev/laravel-policy-engine - 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. dynamik-dev/laravel-policy-engine

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

dynamik-dev/laravel-policy-engine
=================================

A Laravel-native scoped permissions package. Composable, contract-driven authorization that integrates with Gates, Policies, middleware, and Blade.

v0.2.4(1mo ago)114MITPHPPHP ^8.4CI passing

Since Apr 10Pushed 1mo agoCompare

[ Source](https://github.com/dynamik-dev/marque)[ Packagist](https://packagist.org/packages/dynamik-dev/laravel-policy-engine)[ RSS](/packages/dynamik-dev-laravel-policy-engine/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (10)Versions (14)Used By (0)

 [![](./marque.png)](./marque.png)

[![Pint](https://camo.githubusercontent.com/9ffdc7f237be6ea8bbde5db9be21717c8a7052d5b3270ec19373c88761fceba7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f64796e616d696b2d6465762f6d61727175652f6c696e742e796d6c3f6272616e63683d6d61696e266c6162656c3d50696e74266c6f676f3d6c61726176656c267374796c653d666c61742d737175617265)](https://github.com/dynamik-dev/marque/actions/workflows/lint.yml)[![Larastan](https://camo.githubusercontent.com/7f51295eaa6f9b21327a7ee7bd607f2de0c83b907644de43edd28c283a534b06/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f64796e616d696b2d6465762f6d61727175652f7374617469632e796d6c3f6272616e63683d6d61696e266c6162656c3d4c6172617374616e266c6f676f3d706870267374796c653d666c61742d737175617265)](https://github.com/dynamik-dev/marque/actions/workflows/static.yml)[![Pest](https://camo.githubusercontent.com/23187c370b165355cb93846858f9f05432c91a60003e94c11c98fbb4c3eebe6b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f64796e616d696b2d6465762f6d61727175652f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d50657374266c6f676f3d706870267374796c653d666c61742d737175617265)](https://github.com/dynamik-dev/marque/actions/workflows/tests.yml)[![PHPStan Level 9](https://camo.githubusercontent.com/fc5175fc7ebda2f2c039567ea30d325f8eb51212cd498553414daceec4e83194/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230392d3261353039393f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://phpstan.org/)

A [letter of marque](https://en.wikipedia.org/wiki/Letter_of_marque) was a document issued by a government that turned pirates into privateers, granting them scoped permission to plunder in specific waters. This package does the same thing for Laravel (minus the plundering). A user can be an admin in one team and a viewer in another. Deny rules, permission boundaries, and JSON policy documents are built in. The whole thing plugs into Laravel's Gate.

```
composer require dynamik-dev/marque
```

---

Quick look
----------

[](#quick-look)

```
Marque::createRole('admin', 'Admin')
    ->grant(['members.*', 'posts.*'])
    ->assignTo($user, scope: $acmeTeam);

Marque::createRole('viewer', 'Viewer')
    ->grant(['posts.read'])
    ->assignTo($user, scope: $widgetTeam);

$user->can('members.remove', $acmeTeam);  // true
$user->can('members.remove', $widgetTeam); // false
```

Roles, boundaries, and deny rules can live in JSON files you import at deploy time:

```
{
  "roles": [
    {
      "id": "editor",
      "permissions": ["posts.*", "comments.create", "!posts.delete"]
    }
  ],
  "boundaries": [
    { "scope": "plan::free", "max_permissions": ["posts.read", "comments.read"] },
    { "scope": "plan::pro", "max_permissions": ["posts.*", "comments.*", "analytics.*"] }
  ]
}
```

```
php artisan marque:import policies/production.json
```

---

Features
--------

[](#features)

### Wired into the Gate

[](#wired-into-the-gate)

`$user->can()`, `@can`, `$this->authorize()`, and `can:` middleware all work without any extra wiring.

```
$user->assignRole('editor', $acmeOrg);

$user->can('posts.create', $acmeOrg); // true

Route::middleware('can:posts.create')->post('/posts', [PostController::class, 'store']);
```

```
@can('posts.create', $team)
    New Post
@endcan
```

### Deny rules

[](#deny-rules)

Prefix any permission with `!`. The denial overrides every other role that grants it.

```
Marque::createRole('editor', 'Editor')
    ->grant(['posts.*', 'comments.*'])
    ->deny(['posts.delete']);

$editor->can('posts.create');  // true
$editor->can('posts.delete');  // false -- deny wins
```

### Permission boundaries

[](#permission-boundaries)

Boundaries set a ceiling on what any role can do inside a scope. A user with `admin` in a free-tier org still can't access pro-tier features. Pass a scope string or any Scopeable model.

```
Marque::boundary($freeOrg)->permits(['posts.read', 'comments.read']);
Marque::boundary($proOrg)->permits(['posts.*', 'comments.*', 'analytics.*']);

$user->assignRole('admin', $freeOrg);
$user->can('analytics.view', $freeOrg);  // false -- boundary blocks it
$user->can('analytics.view', $proOrg);   // true
```

### Wildcards

[](#wildcards)

```
'posts.*'           // all post actions
'*.read'            // read anything
'*.*'               // superadmin
'posts.update.own'  // fine-grained qualifiers
```

### Resource policies

[](#resource-policies)

Attach authorization rules directly to a resource type. The `when()` closure receives the user and the resource instance.

```
Marque::resource(Post::class)
    ->allow('update')
    ->when(fn ($user, $post) => $post->author_id === $user->id);

Marque::resource(Post::class)
    ->deny('delete');
```

### Contract-driven

[](#contract-driven)

Every component implements a PHP interface. You can swap any implementation through the service container. See [Swapping implementations](docs/extending/swapping-implementations.md).

---

Why not Spatie?
---------------

[](#why-not-spatie)

[Spatie laravel-permission](https://github.com/spatie/laravel-permission) works well for flat RBAC. Marque adds scoped roles, deny rules, permission boundaries, and declarative policy documents. See the [full comparison](docs/comparison-with-spatie.md).

---

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

[](#requirements)

DependencySupported VersionsPHP8.4, 8.5Laravel12, 13PostgreSQL17+SQLite3.35+Valkey / Redis8+SQLite works out of the box for development. PostgreSQL and Valkey are optional — the package tests against both in CI. MySQL is not officially supported but should work fine since Laravel's query builder abstracts the differences.

---

Documentation
-------------

[](#documentation)

**Getting Started** — [How authorization works](docs/getting-started/how-authorization-works.md) | [Installation](docs/getting-started/installing-the-package.md) | [Permission naming](docs/getting-started/permission-naming-conventions.md) | [Seeding permissions and roles](docs/getting-started/seeding-permissions-and-roles.md)

**Authorization** — [Checking permissions](docs/authorization/checking-permissions.md) | [Roles](docs/authorization/working-with-roles.md) | [Scoped permissions](docs/authorization/scoping-permissions.md) | [Deny rules](docs/authorization/using-deny-rules.md) | [Boundaries](docs/authorization/setting-permission-boundaries.md) | [Resource policies](docs/authorization/using-resource-policies.md)

**Integrations** — [Middleware](docs/integrations/restricting-routes-with-middleware.md) | [Blade](docs/integrations/checking-permissions-in-blade.md) | [Model policies](docs/integrations/integrating-with-model-policies.md) | [Sanctum](docs/integrations/scoping-sanctum-tokens.md)

**Policy Documents** — [Document format](docs/policy-documents/document-format.md) | [Import / Export](docs/policy-documents/importing-and-exporting.md)

**Extending** — [Swapping implementations](docs/extending/swapping-implementations.md) | [Events](docs/extending/listening-to-events.md) | [Cache](docs/extending/customizing-the-cache.md)

**Testing** — [Testing authorization](docs/testing/testing-authorization.md)

**Reference** — [Configuration](docs/reference/configuration.md) | [Contracts](docs/reference/contracts.md) | [Facade](docs/reference/facade.md) | [Events](docs/reference/events.md) | [Artisan commands](docs/cli/artisan-commands.md) | [Comparison with Spatie](docs/comparison-with-spatie.md)

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance89

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~1 days

Total

6

Last Release

56d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/12786153?v=4)[Chris Arter](/maintainers/christopherarter)[@christopherarter](https://github.com/christopherarter)

---

Top Contributors

[![christopherarter](https://avatars.githubusercontent.com/u/12786153?v=4)](https://github.com/christopherarter "christopherarter (136 commits)")

---

Tags

laravelauthorizationrolespermissionsrbacPolicyscoped-permissions

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/dynamik-dev-laravel-policy-engine/health.svg)

```
[![Health](https://phpackages.com/badges/dynamik-dev-laravel-policy-engine/health.svg)](https://phpackages.com/packages/dynamik-dev-laravel-policy-engine)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k98.0M1.3k](/packages/spatie-laravel-permission)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k3.5M115](/packages/bezhansalleh-filament-shield)[hasinhayder/tyro

Tyro - The ultimate Authentication, Authorization, and Role &amp; Privilege Management solution for Laravel 12 &amp; 13

6753.6k5](/packages/hasinhayder-tyro)[amdadulhaq/guard-laravel

Guard is Role and Permission management system for Laravel

135.3k](/packages/amdadulhaq-guard-laravel)[wnikk/laravel-access-rules

Simple system of ACR (access control rules) for Laravel, with roles, groups, unlimited inheritance and possibility of multiplayer use.

103.7k1](/packages/wnikk-laravel-access-rules)

PHPackages © 2026

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