PHPackages                             ezappslab/laravel-dominion - 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. ezappslab/laravel-dominion

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

ezappslab/laravel-dominion
==========================

Laravel Dominion is a comprehensive authorization package for Laravel that provides tenant-aware, polymorphic roles and permissions. It is designed for applications that require fine-grained access control across multiple tenants while maintaining a clean, developer-friendly API.

0.3.0(4mo ago)00MITPHPPHP ^8.2

Since Dec 27Pushed 4mo agoCompare

[ Source](https://github.com/ezappslab/laravel-dominion)[ Packagist](https://packagist.org/packages/ezappslab/laravel-dominion)[ RSS](/packages/ezappslab-laravel-dominion/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (10)Versions (3)Used By (0)

Laravel Dominion
================

[](#laravel-dominion)

Laravel Dominion is a comprehensive authorization package for Laravel that provides tenant-aware, polymorphic roles and permissions. It is designed for applications that require fine-grained access control across multiple tenants while maintaining a clean, developer-friendly API.

Dominion solves the complexity of managing permissions in multi-tenant environments by providing explicit allow/deny rules, deterministic precedence, and seamless integration with Laravel's native authorization system.

### Key Use Cases

[](#key-use-cases)

- **Multi-tenant RBAC**: Manage roles and permissions that can be either global or scoped to specific tenants.
- **Polymorphic Authorization**: Assign roles and permissions to any Eloquent model (e.g., Users, API Clients, Teams).
- **Tenant-Aware Gate &amp; Policies**: Automatically resolve the current tenant context for authorization checks.
- **Catalog Syncing**: Keep your database-backed roles and permissions in sync with your codebase using PHP Enums.

---

Core Concepts
-------------

[](#core-concepts)

Dominion is built around several key concepts that work together to provide a robust authorization engine:

- **Domains &amp; Tenancy**: Authorization can be **global** (applies everywhere) or **tenant-scoped** (applies only within a specific tenant).
- **Roles**: Logical groupings of permissions (e.g., `admin`, `editor`).
- **Permissions**: Granular abilities represented by strings (e.g., `posts.update`).
- **Policies**: Dominion integrates with Laravel's policy system to map model actions to permission strings.
- **Services**: Configurable components that handle tenant resolution and value normalization.
- **Allow / Deny**: Explicitly grant or block permissions for a specific principal. **Deny** always takes precedence over **Allow**.

### Precedence Rules

[](#precedence-rules)

When checking if a principal has a permission for a specific tenant, Dominion follows these deterministic rules:

1. **Tenant Deny**: Explicitly denied for the principal in the current tenant.
2. **Global Deny**: Explicitly denied for the principal globally.
3. **Tenant Allow**: Explicitly allowed for the principal in the current tenant.
4. **Global Allow**: Explicitly allowed for the principal globally.
5. **Role-based Permission**: Granted via an assigned role (either tenant-scoped or global).
6. **Default Deny**: If no rules match, access is denied.

---

Architecture
------------

[](#architecture)

Dominion is structured into several layers to ensure flexibility and maintainability:

- **Traits**: Provide the public API (`HasRoles`, `HasPermissions`) for your Eloquent models.
- **Authorization Engine**: The core logic (`AuthorizationResolver`) that evaluates the precedence rules.
- **Contracts**: Replaceable interfaces (`TenantContext`, `PermissionValueResolver`, `RoleValueResolver`) that allow you to customize core behavior.
- **Persistence**: Database tables for roles, permissions, and their polymorphic assignments (`roleables`, `permissionables`).
- **Gate Integration**: Hooks into Laravel's `Gate::before` to provide seamless `$user->can()` checks.

### Authorization Flow

[](#authorization-flow)

1. **Gate Check**: When `$user->can('posts.update')` is called, Dominion's `Gate::before` hook intercepts the call.
2. **Tenant Resolution**: The `TenantContext` service identifies the current tenant ID.
3. **Resolution**: The `AuthorizationResolver` evaluates the precedence rules against the database and returns a boolean.

---

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

[](#installation)

### Requirements

[](#requirements)

- PHP 8.2+
- Laravel 11 or 12

### Steps

[](#steps)

1. **Install via Composer**:

    ```
    composer require ezappslab/laravel-dominion
    ```
2. **Run the Installer**: This command publishes the configuration file (`config/dominion.php`).

    ```
    php artisan dominion:install
    ```
3. **Run Migrations**:

    ```
    php artisan migrate
    ```

---

Configuration
-------------

[](#configuration)

The `config/dominion.php` file allows you to customize almost every aspect of the package.

### Tenancy Configuration

[](#tenancy-configuration)

Define your tenant table and foreign key:

```
'tenant' => [
    'table' => 'tenants',
    'foreign_key' => 'tenant_id',
],
```

### Service Overrides

[](#service-overrides)

You can swap default implementations with your own by updating the `services` array:

```
'services' => [
    'tenant_context' => App\Services\CustomTenantContext::class,
    'permission_value_resolver' => Infinity\Dominion\Services\DefaultPermissionValueResolver::class,
    'role_value_resolver' => Infinity\Dominion\Services\DefaultRoleValueResolver::class,
],
```

---

Roles &amp; Permissions
-----------------------

[](#roles--permissions)

To get started, add the `HasRoles` and `HasPermissions` traits to your model (e.g., `User` model).

### Assigning Roles

[](#assigning-roles)

```
$user->addRole('admin');          // Global role
$user->addRole('member', $tenant); // Tenant-scoped role

$user->removeRole('admin');
```

### Managing Permissions

[](#managing-permissions)

```
$user->allow('posts.update');          // Global allow
$user->allow('posts.update', $tenant); // Tenant-scoped allow

$user->deny('posts.delete');           // Global deny
```

### Checking Access

[](#checking-access)

```
$user->hasRole('admin');
$user->hasPermission('posts.update');

// Native Laravel Gate integration
$user->can('posts.update');
```

---

Policies
--------

[](#policies)

Dominion ships with a `DefaultPolicy` that maps Laravel's policy methods to permission strings using the convention `{table}.{ability}`.

### Enabling the Default Policy

[](#enabling-the-default-policy)

Register your models in `config/dominion.php`:

```
'policy' => [
    'class' => Infinity\Dominion\Policies\DefaultPolicy::class,
    'models' => [
        App\Models\Post::class, // maps update() -> posts.update
    ],
],
```

### Custom Policy Mapping

[](#custom-policy-mapping)

You can also map specific models to your own policy classes:

```
'models' => [
    App\Models\Invoice::class => App\Policies\InvoicePolicy::class,
],
```

---

Enums
-----

[](#enums)

Dominion encourages the use of string-backed PHP Enums for type-safe roles and permissions.

### Defining Enums

[](#defining-enums)

```
enum Role: string {
    case Admin = 'admin';
}

enum PostPermissions: string {
    case Update = 'posts.update';
}
```

### Usage

[](#usage)

```
$user->addRole(Role::Admin);
$user->allow(PostPermissions::Update);
```

---

Services
--------

[](#services)

Dominion relies on internal services that you can extend or replace:

- **`TenantContext`**: Responsible for determining the current tenant ID during authorization checks.
- **`PermissionValueResolver`**: Normalizes permission inputs (strings or enums) into a consistent format.
- **`RoleValueResolver`**: Normalizes role inputs into a consistent format.

To implement a custom service, implement the corresponding contract in `Infinity\Dominion\Contracts` and update your config.

---

Tenancy Support
---------------

[](#tenancy-support)

Dominion is "tenancy-aware" by design. Every role assignment and permission grant can be associated with a `tenant_id`.

### Resolution Flow

[](#resolution-flow)

When an authorization check is performed without an explicit tenant, Dominion calls `TenantContext::currentTenantId()`. This allows you to resolve the tenant from the session, a route parameter, or a header.

### Tenant Argument

[](#tenant-argument)

Most methods accept an optional `$tenant` argument, which can be:

- An Eloquent model instance.
- A primary key (`int` or `string`).
- `null` for global scope.

---

Sync Command
------------

[](#sync-command)

The `dominion:sync` command allows you to synchronize your PHP Enums with the database catalogs.

### Configuration

[](#configuration-1)

Register your enums in `config/dominion.php`:

```
'role_enum' => App\Enums\Role::class,
'permission_enums' => [
    App\Enums\PostPermissions::class,
],
```

### Usage

[](#usage-1)

```
# Basic sync
php artisan dominion:sync

# Preview changes
php artisan dominion:sync --dry-run

# Remove records no longer in enums
php artisan dominion:sync --prune
```

---

Testing &amp; CI
----------------

[](#testing--ci)

When testing applications using Dominion:

- **Seed Permissions**: Use `php artisan dominion:sync` in your test setup to ensure the catalogs are populated.
- **Tenant Context**: If testing tenant-aware logic, ensure your `TenantContext` service is properly mocked or configured for the test environment.
- **Cache**: Dominion caches authorization results. Use `php artisan cache:clear` if you are manually modifying database records during tests.

---

Design Principles
-----------------

[](#design-principles)

- **Explicitness**: Precedence rules are clear and deterministic. Deny always wins.
- **Safety**: Using Enums prevents typos and ensures a single source of truth for your permission set.
- **Predictability**: Dominion honors Laravel's native authorization patterns while adding multi-tenancy.
- **Laravel-Native**: Built to feel like a natural extension of the Laravel framework.

---

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance76

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 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 ~5 days

Total

2

Last Release

131d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7d715ab01fa8a117ea600031ff66c9dde0ea4699dbe7a8ffeb92b97f839af6dd?d=identicon)[Rado Boydev](/maintainers/Rado%20Boydev)

---

Top Contributors

[![rado-boydev](https://avatars.githubusercontent.com/u/152566142?v=4)](https://github.com/rado-boydev "rado-boydev (4 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ezappslab-laravel-dominion/health.svg)

```
[![Health](https://phpackages.com/badges/ezappslab-laravel-dominion/health.svg)](https://phpackages.com/packages/ezappslab-laravel-dominion)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[jeffgreco13/filament-breezy

A custom package for Filament with login flow, profile and teams support.

1.0k1.7M41](/packages/jeffgreco13-filament-breezy)[spatie/laravel-login-link

Quickly login to your local environment

4381.2M1](/packages/spatie-laravel-login-link)[ryangjchandler/laravel-cloudflare-turnstile

A simple package to help integrate Cloudflare Turnstile.

438896.6k2](/packages/ryangjchandler-laravel-cloudflare-turnstile)[spatie/laravel-passkeys

Use passkeys in your Laravel app

444494.4k16](/packages/spatie-laravel-passkeys)

PHPackages © 2026

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