DEV Community

Cover image for The Most Advanced Laravel Permission Manager: Enterprise Authorization Engine with RBAC, ABAC, Role Hierarchy & Multi-Tenancy
Hossein Hezami
Hossein Hezami

Posted on

The Most Advanced Laravel Permission Manager: Enterprise Authorization Engine with RBAC, ABAC, Role Hierarchy & Multi-Tenancy

A complete, production-ready authorization platform for Laravel — combining RBAC, ABAC, Role Hierarchy, Teams, Audit Logging, and 30+ enterprise features in a single package. 141 tests. Zero breaking changes. Works with Laravel 10–13.

🔗 GitHub Repository · 📦 Packagist


📋 Table of Contents


🎯 Introduction

Laravel Permission Manager is the most advanced, enterprise-grade authorization engine available for Laravel applications. It goes far beyond basic role-based access control, delivering a complete authorization platform that combines:

  • 🎭 RBAC (Role-Based Access Control)
  • 🧠 ABAC (Attribute-Based Access Control)
  • 🌳 Role Hierarchy with multi-level inheritance
  • 🏢 Multi-Tenancy / Teams
  • 📝 Audit Logging
  • ⏱️ Temporary Permissions
  • 🔒 Explicit Allow/Deny
  • 🛡️ Advanced Middleware DSL

All in a single, cohesive, backward-compatible package with 141 passing tests and 226 assertions.

Whether you're building a simple blog or a complex SaaS platform with multiple tenants, conditional permissions, and strict audit requirements — this package handles it all.

composer require hosseinhezami/laravel-permission-manager
Enter fullscreen mode Exit fullscreen mode

⚡ Quick Start (5 Minutes)

Step 1: Install & Publish

composer require hosseinhezami/laravel-permission-manager
php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="migrations"
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Step 2: Add Trait to User Model

use HosseinHezami\PermissionManager\Traits\PermissionTrait;

class User extends Authenticatable
{
    use PermissionTrait;
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Roles & Assign Permissions

php artisan role:create admin "Administrator" "Full system access"
php artisan permission:create "users.view"
php artisan permission:create "users.edit"
php artisan role:assign-permission admin "users.view,users.edit"
Enter fullscreen mode Exit fullscreen mode

Step 4: Assign Role & Check Access

$user->assignRole('admin');
$user->hasPermissionTo('users.view'); // true
Enter fullscreen mode Exit fullscreen mode

That's it. A fully functional RBAC system in under 5 minutes. But this is just the surface...


🎯 Core Authorization Features

1. Role-Based Access Control (RBAC)

The foundation of the system. Multiple roles per user, permissions assigned to roles.

$user->assignRole('admin');
$user->assignRole(['editor', 'manager']);
$user->revokeRole('editor');

$user->hasRole('admin');                        // true
$user->hasAnyRole(['admin', 'super-admin']);    // true
$user->hasAllRoles(['admin', 'manager']);       // true
$user->lacksRole('super-admin');                // true
Enter fullscreen mode Exit fullscreen mode

2. Direct User Permissions

Grant permissions directly to a user without needing a role. Perfect for exceptions, one-off access, or special cases.

// Grant direct permission
$user->givePermissionTo('reports.export');

// Check it
$user->hasDirectPermission('reports.export'); // true

// Deny directly
$user->denyPermissionTo('users.delete');

// Revoke
$user->revokePermissionTo('reports.export');
Enter fullscreen mode Exit fullscreen mode

3. Explicit Allow / Deny System

The deny permission has higher priority than allow. This enables powerful exception-based access control.

// Role grants all posts.* permissions
$editor->assignPermission('posts.*');

// But this specific user cannot delete
$user->denyPermissionTo('posts.delete');

// Result:
$user->hasPermissionTo('posts.edit');   // ✅ true (from role wildcard)
$user->hasPermissionTo('posts.delete'); // ❌ false (explicit deny wins)
Enter fullscreen mode Exit fullscreen mode

Resolution Order (highest → lowest priority):

1. Super Admin bypass
2. Explicit User DENY        ← highest
3. Explicit Role DENY
4. Explicit User ALLOW
5. Role ALLOW
6. Inherited Role permissions
7. Wildcard matching
8. Default: DENY             ← lowest
Enter fullscreen mode Exit fullscreen mode

4. Wildcard Permissions

Flexible pattern matching with negation support:

$role->assignPermission('users.*');        // All user operations
$role->assignPermission('*.edit');         // All edit operations
$role->assignPermission('admin.*');        // All admin operations
$role->assignPermission('!users.delete');  // Everything EXCEPT users.delete
Enter fullscreen mode Exit fullscreen mode
Pattern Matches Doesn't Match
users.* users.edit, users.delete posts.edit
*.edit users.edit, posts.edit users.view
* Everything Nothing
!users.delete Everything except users.delete users.delete

5. Role Hierarchy (Multi-Level Inheritance)

Roles can inherit from other roles, creating powerful permission chains:

// Build hierarchy: super-admin → admin → editor → viewer
$superAdmin->inheritFrom('admin');
$admin->inheritFrom('editor');
$editor->inheritFrom('viewer');

// Assign specific permissions at each level
$viewer->assignPermission('posts.view');
$editor->assignPermission('posts.edit');
$admin->assignPermission('posts.delete');
$superAdmin->assignPermission('system.config');

// A user with super-admin gets ALL permissions through the chain
$user->assignRole('super-admin');
$user->hasPermissionTo('posts.view');     // ✅ from viewer (3 levels up)
$user->hasPermissionTo('posts.edit');     // ✅ from editor (2 levels up)
$user->hasPermissionTo('posts.delete');   // ✅ from admin (1 level up)
$user->hasPermissionTo('system.config');  // ✅ from super-admin (direct)
Enter fullscreen mode Exit fullscreen mode

Cycle Detection

The system automatically prevents circular inheritance:

$roleA->inheritFrom('roleB');
$roleB->inheritFrom('roleA'); 
// ❌ Throws CyclicRoleInheritanceException
Enter fullscreen mode Exit fullscreen mode

6. Temporary / Expiring Permissions

Grant time-limited access that automatically expires:

// 24-hour access
$user->givePermissionTo('reports.export', 'allow', now()->addDay());

// 30-day contractor access
$user->givePermissionTo('projects.access', 'allow', now()->addDays(30));

// After expiration → automatically returns false
// No cron job needed for permission checks!

// Clean up expired records weekly
php artisan permission:prune --days=7
Enter fullscreen mode Exit fullscreen mode

7. Super Admin Bypass

Configurable root access that skips all permission checks:

// config/permission-manager.php
'super_admin' => [
    'enabled' => true,
    'role_slug' => 'super-admin',
    'bypass_all' => true,
],

// Usage
$user->isSuperAdmin();                        // true
$user->hasPermissionTo('anything.xyz.123');   // true (bypasses everything)
Enter fullscreen mode Exit fullscreen mode

🏢 Enterprise Features

8. Teams / Multi-Tenancy

Essential for SaaS applications where users belong to multiple organizations:

// Create teams
$engineering = Team::createTeam(['name' => 'Engineering', 'slug' => 'engineering']);
$marketing = Team::createTeam(['name' => 'Marketing', 'slug' => 'marketing']);

// User joins both teams
$user->joinTeam($engineering);
$user->joinTeam($marketing);

// Different roles per team
$user->assignRoleForTeam('admin', $engineering);
$user->assignRoleForTeam('editor', $marketing);

// Check team-specific roles
$user->hasRoleForTeam('admin', $engineering);   // true
$user->hasRoleForTeam('admin', $marketing);     // false
$user->hasRoleForTeam('editor', $marketing);    // true

// Leave team
$user->leaveTeam($marketing);
Enter fullscreen mode Exit fullscreen mode

Team Context in Requests

// Via middleware
Route::middleware(['pm.team:header,X-Team-Id'])->group(function () {
    // All permissions scoped to team from X-Team-Id header
});

// Programmatically
PermissionManager::setTeam($currentTeam);
$user->hasPermissionTo('projects.view'); // Scoped to current team
PermissionManager::clearTeam();
Enter fullscreen mode Exit fullscreen mode

9. ABAC (Attribute-Based Access Control)

The most powerful feature. Define conditions that must be met for a permission to grant access:

// Only allow editing if user owns the post AND it's a draft
PermissionCondition::create([
    'permission_id' => $permission->id,
    'name' => 'owner-and-draft',
    'conditions' => [
        'all' => [
            ['field' => 'user.id', 'operator' => '=', 'value' => 'resource.owner_id'],
            ['field' => 'resource.status', 'operator' => '=', 'value' => 'draft'],
        ],
    ],
]);

// Usage
$user->canPermission('posts.update', $post);
// Returns true ONLY if $user->id === $post->owner_id AND $post->status === 'draft'
Enter fullscreen mode Exit fullscreen mode

Supported Operators

Operator Description Example
= == Equal user.id = resource.owner_id
!= !== Not equal user.role != "banned"
> >= Greater than user.level >= resource.required_level
< <= Less than user.failed_attempts < 3
in In array resource.status in ["draft", "pending"]
not_in Not in array user.id not_in [1, 2, 3]
contains String contains user.email contains "@company.com"
starts_with String starts with resource.path starts_with "admin/"
exists Is not null resource.published_at exists
not_exists Is null resource.deleted_at not_exists

Logical Operators & Nesting

// AND (all must match)
['all' => [...conditions]]

// OR (any must match)
['any' => [...conditions]]

// NOT (negate)
['not' => ...condition]

// Complex nesting
['all' => [
    ['field' => 'resource.status', 'operator' => '!=', 'value' => 'archived'],
    ['any' => [
        ['field' => 'user.id', 'operator' => '=', 'value' => 'resource.owner_id'],
        ['field' => 'user.role', 'operator' => '=', 'value' => 'admin'],
    ]],
]]
Enter fullscreen mode Exit fullscreen mode

🔒 Security: The condition engine uses a whitelist-based evaluator. No eval(), no code execution. Only safe, predefined operators.

10. Audit Logging

Track every permission change with full context:

// Automatically logged when you:
$user->assignRole('admin');
$role->assignPermission('users.delete');
$user->givePermissionTo('reports.export');

// Query the audit trail
PermissionAudit::byActor($adminId)->get();
PermissionAudit::action('granted')->latest()->limit(50)->get();

// Each record includes:
// - actor_id (who made the change)
// - action (granted, revoked, created, etc.)
// - subject_type (user, role, permission)
// - ip_address, user_agent
// - metadata (JSON)
Enter fullscreen mode Exit fullscreen mode

11. Authorization Audit Trail

Optionally log every permission check (not just mutations):

// config/permission-manager.php
'authorization_logging' => [
    'enabled' => true,
    'denied_only' => true,     // Only log failed attempts
    'sample_rate' => 0.1,      // Log 10% (for high-traffic apps)
],
Enter fullscreen mode Exit fullscreen mode

12. Multi-Guard Support

True isolation between authentication guards:

// Create guard-specific roles
Role::create(['name' => 'Web Admin', 'slug' => 'web-admin', 'guard_name' => 'web']);
Role::create(['name' => 'API Admin', 'slug' => 'api-admin', 'guard_name' => 'api']);

// Query by guard
Role::forGuard('web')->get();
Role::forGuard('api')->get();
Permission::forGuard('api')->get();
Enter fullscreen mode Exit fullscreen mode

13. Permission Groups & Sets

Organize hundreds of permissions logically:

// Groups (categories for UI)
$group = PermissionGroup::createGroup(['name' => 'User Management', 'slug' => 'user-mgmt']);
$permission->assignToGroup('user-mgmt');

// Sets (bundles for quick assignment)
$set = PermissionSet::createSet(['name' => 'Content Manager', 'slug' => 'content-manager']);
$set->assignPermissions(['posts.view', 'posts.create', 'posts.edit', 'posts.publish']);

// Assign entire set to a role
$role->assignPermissionSet('content-manager');
Enter fullscreen mode Exit fullscreen mode

🔐 Laravel Integration

14. Native Gate Integration

All permissions automatically register with Laravel's Gate via Gate::before():

// These all work out of the box:
$user->can('users.edit');
$user->cannot('users.delete');

// In Blade
@can('users.edit')
    <button>Edit</button>
@endcan

// In Controllers
Gate::authorize('users.edit');
Gate::allows('users.edit');
Gate::denies('users.delete');
Enter fullscreen mode Exit fullscreen mode

15. Advanced Middleware DSL

Protect routes with a powerful, expressive syntax:

// Single permission
Route::get('/users', fn() => '...')
    ->middleware('pm:permission:users.view');

// ANY of these (OR logic)
Route::get('/users', fn() => '...')
    ->middleware('pm:permission:any:users.view|users.list');

// ALL of these (AND logic)
Route::post('/users', fn() => '...')
    ->middleware('pm:permission:all:users.view|users.create');

// NOT this permission
Route::get('/public', fn() => '...')
    ->middleware('pm:permission:not:admin.panel');

// Role checks
Route::get('/admin', fn() => '...')
    ->middleware('pm:role:admin|manager|editor');

// Combined (AND between directives)
Route::get('/reports', fn() => '...')
    ->middleware(['pm:role:admin', 'pm:permission:reports.view']);
Enter fullscreen mode Exit fullscreen mode

16. Blade Directives (12+)

@role('admin')
    <span>Welcome, Admin!</span>
@endrole

@permission('users.edit')
    <button>Edit User</button>
@endpermission

@hasanyrole(['admin', 'editor'])
    <span>You can edit content</span>
@endhasanyrole

@hasallroles(['verified', 'premium'])
    <span>Premium Verified User</span>
@endhasallroles

@unlesspermission('users.delete')
    <span class="text-muted">Delete disabled</span>
@endunlesspermission

@canpermission('posts.update', $post)
    <a href="{{ route('posts.edit', $post) }}">Edit</a>
@endcanpermission
Enter fullscreen mode Exit fullscreen mode

17. Custom Abilities (Policy Integration)

Define complex authorization logic:

PermissionManager::define('posts.update', function ($user, $post) {
    return $post->user_id === $user->id 
        || $user->hasPermissionTo('posts.edit.any');
});

// Usage
$user->canPermission('posts.update', $post);
Enter fullscreen mode Exit fullscreen mode

🛠️ Developer Experience

18. Explain API (Debugging)

Get detailed explanations of authorization decisions:

$result = PermissionManager::explain($user, 'orders.delete');

// Returns:
[
    'allowed' => false,
    'ability' => 'orders.delete',
    'reason' => 'explicit_user_deny',
    'source' => 'direct_permission',
    'metadata' => [
        'matched_pattern' => 'orders.delete',
        'permission_id' => 42,
    ],
    'user' => [
        'id' => 1,
        'roles' => ['admin', 'editor'],
        'direct_permissions' => ['orders.view', '!orders.delete'],
    ],
]
Enter fullscreen mode Exit fullscreen mode

19. Permission Snapshot

Debug a user's complete authorization state:

$snapshot = PermissionManager::snapshot($user);
// Returns: roles, allow list, deny list, inherited roles, permissions, context
Enter fullscreen mode Exit fullscreen mode

20. Rich CLI Commands (24 total)

# 🩺 System health check
php artisan permission:doctor

# 🌳 View role hierarchy tree
php artisan permission:tree

# ❓ Why was access denied?
php artisan permission:why 42 users.delete

# 📋 Explain permission (JSON output)
php artisan permission:explain 42 users.edit --json

# ✅ Validate configuration
php artisan permission:validate

# ✂️ Prune expired permissions
php artisan permission:prune --days=30

# ⚡ Cache management
php artisan permission:cache:warm
php artisan permission:cache:clear

# 📦 Generate CRUD permissions
php artisan permission:generate-resource users

# 🔄 Sync routes (3 strategies)
php artisan permission:sync-routes --strategy=controller-action

# Standard CRUD
php artisan role:create admin "Administrator"
php artisan permission:create "users.view"
php artisan role:assign-permission admin "users.*"
php artisan user:assign-role 1 admin
php artisan role:export roles.json
php artisan role:import roles.json
Enter fullscreen mode Exit fullscreen mode

Example: permission:why

$ php artisan permission:why 42 users.delete

┌─────────────────────────────────────────────────┐
│  Permission Decision Explanation                │
└─────────────────────────────────────────────────┘

  User:    42
  Ability: users.delete

  ✗ DENIED

  Reason:  explicit_user_deny
  Source:  direct_permission
  Details:
    - matched_pattern: users.delete
    - permission_id: 15
Enter fullscreen mode Exit fullscreen mode

21. Smart Caching

Hierarchical cache invalidation that actually works:

// When a permission changes:
// 1. Permission cache invalidated
// 2. All roles with that permission invalidated
// 3. All users with those roles invalidated

// Manual cache control
PermissionManager::cache()->flushAll();
PermissionManager::cache()->flushUser($userId);
PermissionManager::cache()->flushRole($roleId);
Enter fullscreen mode Exit fullscreen mode

Supports Cache Tags for Redis/Memcached drivers.

22. Testing Helpers

Built-in helpers for application tests:

use HosseinHezami\PermissionManager\Testing\InteractsWithPermissions;
use HosseinHezami\PermissionManager\Testing\PermissionAssertions;

class PostControllerTest extends TestCase
{
    use InteractsWithPermissions;
    use PermissionAssertions;

    public function test_admin_can_edit_posts()
    {
        $admin = $this->createUserWithRoles(['admin']);

        $this->assertHasRole($admin, 'admin');
        $this->assertHasPermission($admin, 'posts.edit');
        $this->assertDoesNotHavePermission($admin, 'system.config');
    }

    public function test_unauthorized_gets_403()
    {
        $user = $this->createUser();

        $this->actingAs($user)
            ->get('/admin/users')
            ->assertStatus(403);
    }
}
Enter fullscreen mode Exit fullscreen mode

23. Fluent Facade API

use HosseinHezami\PermissionManager\Facades\PermissionManager;

// Roles
PermissionManager::roles()->list();
PermissionManager::roles()->create(['slug' => 'admin', 'name' => 'Administrator']);
PermissionManager::role('admin')->assignPermission('users.*');
PermissionManager::role('admin')->inheritFrom('editor');

// Permissions
PermissionManager::permissions()->create('users.view');
PermissionManager::permissions()->sync();
PermissionManager::permissions()->generateResource('posts');

// Users
PermissionManager::user($userId)->assignRole('admin');
PermissionManager::user($userId)->hasPermission('users.edit');

// Authorization
PermissionManager::check($user, 'users.edit');
PermissionManager::explain($user, 'orders.delete');
PermissionManager::snapshot($user);

// Teams
PermissionManager::setTeam($team);
PermissionManager::clearTeam();

// Cache
PermissionManager::cache()->flushAll();
Enter fullscreen mode Exit fullscreen mode

🏗️ Architecture Overview

The Authorization Engine

All permission checks flow through a single, centralized engine:

Request → Middleware / Gate / Blade
              ↓
     AuthorizationManager
              ↓
    ┌─────────────────────┐
    │ 1. Super Admin?     │ → BYPASS
    │ 2. User DENY?       │ → DENY
    │ 3. Role DENY?       │ → DENY
    │ 4. User ALLOW?      │ → ALLOW
    │ 5. Role ALLOW?      │ → ALLOW
    │ 6. Inherited?       │ → ALLOW
    │ 7. Conditions?      │ → EVALUATE
    │ 8. Default          │ → DENY
    └─────────────────────┘
              ↓
     AuthorizationResult
     (allowed, reason, source, metadata)
Enter fullscreen mode Exit fullscreen mode

Database Schema (14 Tables)

roles                    permissions              permission_groups
role_permissions         user_roles               user_permissions
role_inherits            permission_sets           permission_set_items
teams                    team_user                permission_conditions
permission_audits        authorization_logs
Enter fullscreen mode Exit fullscreen mode

Source Structure (73 files)

src/
├── Authorization/       (9 files - Core engine)
├── Console/            (24 files - CLI commands)
├── Events/             (6 files)
├── Exceptions/         (6 files)
├── Handlers/           (2 files)
├── Listeners/          (2 files)
├── Middleware/         (3 files)
├── Models/             (10 files)
├── Proxies/            (2 files)
├── Services/           (2 files)
├── Support/            (5 files)
├── Testing/            (2 files)
├── Traits/             (1 file)
└── Root files          (2 files)
Enter fullscreen mode Exit fullscreen mode

💡 Real-World Examples

E-commerce Platform

// Hierarchy: super-admin > admin > seller > customer
$seller->inheritFrom('customer');
$admin->inheritFrom('seller');

// Conditional: sellers can only edit their own products
PermissionCondition::create([
    'permission_id' => Permission::findByRoute('products.edit')->id,
    'conditions' => [
        'field' => 'user.id',
        'operator' => '=',
        'value' => 'resource.seller_id',
    ],
]);
Enter fullscreen mode Exit fullscreen mode

Multi-Tenant SaaS

$companyA = Team::createTeam(['name' => 'Company A']);
$companyB = Team::createTeam(['name' => 'Company B']);

$user->joinTeam($companyA);
$user->joinTeam($companyB);

$user->assignRoleForTeam('admin', $companyA);
$user->assignRoleForTeam('viewer', $companyB);
Enter fullscreen mode Exit fullscreen mode

Contractor with Time-Limited Access

$contractor->givePermissionTo('projects.access', 'allow', now()->addDays(30));
$contractor->givePermissionTo('billing.view', 'allow', now()->addDays(7));
// Automatically expires. No cron job needed for checks.
Enter fullscreen mode Exit fullscreen mode

Approval Workflow

// Managers can approve expenses under $1000
PermissionCondition::create([
    'permission_id' => Permission::findByRoute('expenses.approve')->id,
    'conditions' => [
        'all' => [
            ['field' => 'user.role', 'operator' => '=', 'value' => 'manager'],
            ['field' => 'resource.amount', 'operator' => '<=', 'value' => 1000],
        ],
    ],
]);
Enter fullscreen mode Exit fullscreen mode

🧪 Testing & Quality

The package ships with 141 passing tests and 226 assertions:

✅ Unit Tests        → WildcardMatcher, ConditionEvaluator, MiddlewareParser, CacheKeys
✅ Feature Tests     → Trait, Models, Middleware, Blade, Commands, Gate, Proxy
✅ Integration Tests → Hierarchy, Teams, ABAC, Expiry, Cache, Audit
Enter fullscreen mode Exit fullscreen mode

All tests run against SQLite in-memory — completely isolated, fast, and safe.

composer test              # All 141 tests
composer test-unit         # Unit only
composer test-feature      # Feature only
composer test-integration  # Integration only
Enter fullscreen mode Exit fullscreen mode

📦 Installation & Configuration

Requirements

  • PHP 8.2+
  • Laravel 10, 11, 12, or 13

Install

composer require hosseinhezami/laravel-permission-manager
Enter fullscreen mode Exit fullscreen mode

Publish & Migrate

php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="config"
php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="migrations"
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Configuration Highlights

// config/permission-manager.php
return [
    'cache_duration' => 60,
    'wildcards' => true,

    'super_admin' => [
        'enabled' => true,
        'role_slug' => 'super-admin',
        'bypass_all' => true,
    ],

    'teams' => ['enabled' => true],
    'audit' => ['enabled' => true, 'log_mutations' => true],
    'conditions' => ['enabled' => true],

    'authorization_logging' => [
        'enabled' => false,
        'denied_only' => true,
        'sample_rate' => 1.0,
    ],
];
Enter fullscreen mode Exit fullscreen mode

🔗 Links


📊 Comparison with Spatie Laravel Permission

Feature Laravel Permission Manager Spatie Permission
RBAC
Direct Permissions
Wildcard Permissions ✅ (advanced + negation)
Explicit Allow/Deny
Role Hierarchy ✅ Multi-level + cycle detection
Temporary Permissions ✅ Auto-expiry
Teams / Multi-Tenancy
Multi-Guard (real) ✅ guard_name column
ABAC / Conditions ✅ JSON engine (no eval)
Audit Logging ✅ Built-in
Authorization Trail ✅ Configurable
Explain API
Permission Snapshot
CLI Doctor
CLI Why/Explain
Permission Tree
Resource Generator
Route Sync ✅ (3 strategies)
Permission Groups
Permission Sets
Gate Integration ✅ Native
Middleware DSL ✅ any/all/not
Blade Directives ✅ 12+
Smart Caching ✅ Hierarchical
Testing Helpers ✅ Built-in
Events ✅ 6 events
Import/Export ✅ JSON
Tests 141 ~300
Laravel 13 Support ⚠️
Backward Compatible ✅ 100%

💬 Final Thoughts

Laravel Permission Manager v2.0 is not just another permission package. It's a complete enterprise authorization platform that handles everything from simple RBAC to complex ABAC with conditions, multi-tenancy, audit trails, and hierarchical role structures.

Whether you're building a startup MVP or a large-scale SaaS platform, this package scales with your needs — without requiring you to switch packages or write custom authorization logic.

composer require hosseinhezami/laravel-permission-manager
Enter fullscreen mode Exit fullscreen mode

Star ⭐ it on GitHub if you find it useful!


🔗 GitHub Repository · 📦 Packagist


Built with ❤️ by Hossein Hezami · MIT License


Tags: laravel, php, authorization, rbac, abac, permissions, access-control, multi-tenancy, security, opensource, laravel-package, role-management

Top comments (0)