PHPackages                             edulazaro/larallow - 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. edulazaro/larallow

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

edulazaro/larallow
==================

Roles and permissions support for Laravel

1.1.1(5mo ago)662.8k↑55.6%1[1 issues](https://github.com/edulazaro/larallow/issues)MITPHPPHP ^8.2

Since Jun 1Pushed 5mo agoCompare

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

READMEChangelog (10)Dependencies (4)Versions (23)Used By (0)

Larallow for Laravel: A package to handle roles and permissions
===============================================================

[](#larallow-for-laravel-a-package-to-handle-roles-and-permissions)

 [![Total Downloads](https://camo.githubusercontent.com/0ba04cf4185e3a29be0443301693e1f009b006b9b967f62716fb9548e131ba48/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6564756c617a61726f2f6c6172616c6c6f77)](https://packagist.org/packages/edulazaro/larallow) [![Latest Stable Version](https://camo.githubusercontent.com/5d7a7a269518743dd1622c56019669988845b9ec831733159a80621db482b20e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6564756c617a61726f2f6c6172616c6c6f77)](https://packagist.org/packages/edulazaro/larallow)

**Larallow** is a flexible Laravel package for managing roles and permissions with advanced features including scoped roles and permissions, polymorphic relations, translation support, and seamless integration with PHP enums for permissions. Zero configuration required.

Why this package when Spatie Permissions exists?

Spatie Permissions is a great package. However it stores permissions in the database by default and does not handle well scopes or permissions for different actors, also requiring to specify the guard for each permission. It's all about your preferences and project requirements.

Features
--------

[](#features)

- Manage roles and permissions for any actor model (User, Client, etc.)
- Support for scoped roles via polymorphic roleable models (e.g., specific projects, teams)
- Support for scoped permissions via polymorphic permissionable models (e.g., specific resources)
- Define permissions with a fluent API in a similar way you define Laravel routes
- Fluent querying and checking with Permissions and Roles helper classes
- Built-in translation support for role names without external packages
- Permission hierarchy (implications)

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

[](#installation)

Add the package via Composer:

```
composer require edulazaro/larallow

```

Publish migrations and run them:

```
php artisan vendor:publish --tag=larallow
php artisan migrate

```

Quick Start
-----------

[](#quick-start)

### 1. Add traits to your model

[](#1-add-traits-to-your-model)

```
use EduLazaro\Larallow\Concerns\HasPermissions;
use EduLazaro\Larallow\Concerns\HasRoles;

class User extends Authenticatable
{
    use HasPermissions, HasRoles;
}
```

### 2. Define permissions (in a service provider)

[](#2-define-permissions-in-a-service-provider)

```
use EduLazaro\Larallow\Permission;

Permission::create([
    'edit-post' => 'Edit Post',
    'delete-post' => 'Delete Post',
])->for(User::class);
```

### 3. Assign and check permissions

[](#3-assign-and-check-permissions)

```
// Assign a permission
$user->allow('edit-post');

// Or using the permissions() method
$user->permissions('edit-post')->allow();

// Check if user has permission (direct or via role)
$user->permissions('edit-post')->check();

// Check direct permission only
$user->hasPermission('edit-post');
```

### 4. Work with roles

[](#4-work-with-roles)

```
use EduLazaro\Larallow\Models\Role;

// Create a role
$role = Role::create(['handle' => 'editor', 'name' => 'Editor']);

// Add permissions to the role
$role->addPermission('edit-post');

// Assign role to user
$user->assignRole($role);

// Check role
$user->hasRole('editor');
```

---

Setup
-----

[](#setup)

### Actor Traits

[](#actor-traits)

Add the `HasPermissions` and `HasRoles` traits to your actor models (User, Client, etc.):

```
use EduLazaro\Larallow\Concerns\HasPermissions;
use EduLazaro\Larallow\Concerns\HasRoles;

class User extends Authenticatable
{
    use HasPermissions, HasRoles;
}
```

You can use only one trait if you don't need both features.

### Role Tenant Trait

[](#role-tenant-trait)

For models that own roles (e.g., Account, Group, Organization), add the `IsRoleTenant` trait:

```
use EduLazaro\Larallow\Concerns\IsRoleTenant;

class Account extends Model
{
    use IsRoleTenant;
}
```

This allows you to retrieve roles belonging to that tenant:

```
$roles = $account->roles()->get();
```

### Morph Maps (Recommended)

[](#morph-maps-recommended)

For consistent and secure morph relationships, define all models in your morph map:

```
use Illuminate\Database\Eloquent\Relations\Relation;

// In AppServiceProvider boot()
Relation::morphMap([
    'user' => User::class,
    'client' => Client::class,
    'office' => Office::class,
]);
```

This is optional but heavily recommended, especially when dealing with multiple actor types or scopes.

---

Permissions
-----------

[](#permissions)

### Defining Permissions

[](#defining-permissions)

Register permissions using `Permission::create()` in a service provider:

```
use EduLazaro\Larallow\Permission;

// Single permission
Permission::create('edit-post')->label('Edit Post');

// Multiple permissions
Permission::create([
    'edit-post' => 'Edit Post',
    'delete-post' => 'Delete Post',
    'view-post' => 'View Post',
]);
```

#### For specific actor types

[](#for-specific-actor-types)

Use `for()` to restrict permissions to specific actor models:

```
Permission::create('edit-post')->for(User::class);
Permission::create('manage-account')->for([User::class, Client::class]);

// Using morph map names
Permission::create('edit-post')->for('user');
```

#### For specific scopes

[](#for-specific-scopes)

Use `on()` to restrict permissions to specific scope models (e.g., Office, Group):

```
Permission::create('manage-office')
    ->for(User::class)
    ->on(Office::class);

// Multiple scopes
Permission::create('manage-resources')
    ->for(User::class)
    ->on([Office::class, Group::class]);
```

#### Grouping permissions

[](#grouping-permissions)

Define multiple permissions with shared configuration:

```
Permission::create([
    'manage-clients' => 'Manage Clients',
    'manage-properties' => 'Manage Properties',
    'manage-appointments' => 'Manage Appointments',
])->for(User::class)
  ->on([Office::class, Group::class]);
```

#### Permission implications (hierarchy)

[](#permission-implications-hierarchy)

Define permission hierarchies where higher-level permissions imply lower-level ones:

```
Permission::create('manage-posts')
    ->for(User::class)
    ->implies('edit-post');

Permission::create('edit-post')->for(User::class);

// Users with 'manage-posts' automatically have 'edit-post'
```

#### Using enums

[](#using-enums)

```
Permission::create(UserPermission::EditPost->value)->label('Edit Post');

Permission::create([
    UserPermission::EditPost->value => 'Edit Post',
    UserPermission::DeletePost->value => 'Delete Post',
])->for(User::class);
```

#### Translating permission labels

[](#translating-permission-labels)

```
Permission::create([
    'edit-post' => __('Edit Post'),
]);
```

Or for easier text management you can use [Laratext](https://github.com/edulazaro/laratext) package:

```
Permission::create([
    'edit-post' => text('edit_post', 'Edit Post'),
]);
```

### Assigning Permissions

[](#assigning-permissions)

Assign permissions directly to actors:

```
// Single permission
$user->allow('edit-post');
$user->allow(UserPermission::EditPost);

// Multiple permissions
$user->allow(['edit-post', 'delete-post']);
```

#### With scope

[](#with-scope)

```
$office = Office::find(1);
$user->allow('manage-office', $office);
```

#### Alternative syntax

[](#alternative-syntax)

```
$user->permissions('edit-post')->allow();
$user->permissions(['edit-post', 'delete-post'])->allow();
```

### Removing Permissions

[](#removing-permissions)

```
$user->deny('edit-post');

// With scope
$user->deny('manage-office', $office);

// Alternative
$user->permissions('edit-post')->deny();
```

### Syncing Permissions

[](#syncing-permissions)

Sync permissions to match a given list (adds missing, removes others):

```
$user->syncPermissions(['edit-post', 'view-post']);

// With scope
$user->syncPermissions(['manage-office'], $office);
```

### Checking Permissions

[](#checking-permissions)

#### Direct permissions only

[](#direct-permissions-only)

Check if user has a permission directly assigned (not via roles):

```
$user->hasPermission('edit-post');
$user->hasPermission('edit-post', $scope);

// Multiple (all required)
$user->hasPermissions(['edit-post', 'delete-post']);
```

You can also retrieve the list of permissions directly assigned to an actor:

```
$permissions = $user->permissions; // Collection of ActorPermission models

foreach ($permissions as $permission) {
    echo $permission->permission; // string permission name
}

// Query specific permissions
$canEdit = $user->permissions()->where('permission', 'edit-post')->exists();
```

#### Combined (direct + role-based)

[](#combined-direct--role-based)

Check if user has permission either directly or via a role:

```
// Model method (simplest)
$user->permissions('edit-post')->check();

// With scope
$user->permissions('edit-post')->on($office)->check();

// Helper function
permissions('edit-post')->for($user)->check();

// Permissions class (verbose)
Permissions::query()
    ->permissions('edit-post')
    ->for($user)
    ->check();
```

#### Check any vs all

[](#check-any-vs-all)

```
// True if user has ANY of these permissions
$user->permissions(['edit-post', 'delete-post'])->check();

// True only if user has ALL permissions
$user->permissions(['edit-post', 'delete-post'])->checkAll();

// With scope
$user->permissions(['edit-post', 'delete-post'])->on($office)->checkAll();
```

#### Blade directives

[](#blade-directives)

```
@permissions('edit-post')
    Edit Post
@endpermissions

@allpermissions(['edit-post', 'delete-post'])
    Manage Post
@endallpermissions

// With scope
@permissions('edit-post', $scope)
    Edit Post
@endpermissions
```

---

Roles
-----

[](#roles)

### Creating Roles

[](#creating-roles)

```
use EduLazaro\Larallow\Models\Role;

$role = Role::create([
    'handle' => 'editor',
    'name' => 'Editor',
]);

// With tenant and scope restrictions
$role = new Role();
$role->handle = 'office_manager';
$role->name = 'Office Manager';
$role->tenant_type = $tenant->getMorphClass();
$role->tenant_id = $tenant->id;
$role->actor_type = 'user';
$role->scope_type = 'office';
$role->save();
```

### Assigning Roles

[](#assigning-roles)

```
$user->assignRole($role);
$user->assignRole($roleId);

// Multiple roles
$user->assignRoles([$role1, $role2, $roleId]);

// With scope
$user->assignRole($role, $office);
$user->assignRoles([$role1, $role2], $office);
```

#### With tenant (multi-tenancy)

[](#with-tenant-multi-tenancy)

```
Roles::query()
    ->roles($roles)
    ->for($user)
    ->on($office)
    ->tenant($group)
    ->assign();
```

### Removing Roles

[](#removing-roles)

```
$user->removeRole($role);
$user->removeRole($role, $scope);
```

### Syncing Roles

[](#syncing-roles)

Sync roles to match a given list:

```
$user->syncRoles([$role1, $role2]);
$user->syncRoles([1, 2, $roleInstance]);

// With scope (only affects roles for that scope)
$user->syncRoles([$managerRole], $office);
```

### Checking Roles

[](#checking-roles)

```
$user->hasRole('editor');
$user->hasRole('editor', $scope);
```

You can also retrieve the roles assigned to an actor:

```
$roles = $user->roles; // Collection of Role models

foreach ($roles as $role) {
    echo $role->handle;
}
```

#### Check any vs all

[](#check-any-vs-all-1)

```
// Any of these roles
$user->roles(['editor', 'admin'])->check();

// All of these roles
$user->roles(['editor', 'admin'])->checkAll();

// With scope
$user->roles(['editor', 'admin'])->on($scope)->checkAll();

// Using helper
roles(['editor', 'admin'])->for($user)->check();

// Using Roles class (verbose)
Roles::query()
    ->roles(['editor', 'admin'])
    ->for($user)
    ->check();
```

#### Blade directives

[](#blade-directives-1)

```
@roles(['admin', 'editor'])
    You have elevated access.
@endroles

@allroles(['admin', 'editor'])
    You have full admin/editor access.
@endallroles
```

### Role Permissions

[](#role-permissions)

Add permissions to roles:

```
$role->addPermission('edit-post');
$role->addPermission(['edit-post', 'delete-post', 'view-post']);
```

Remove permissions from roles:

```
$role->removePermission('edit-post');
$role->removePermission(['edit-post', 'delete-post']);
```

You can also use the relationship directly:

```
$role->permissions()->create(['permission' => 'edit-post']);
$role->permissions()->where('permission', 'edit-post')->delete();
```

### Checking Role Permissions

[](#checking-role-permissions)

Check if user has permissions through their roles (ignoring direct permissions):

```
// Single permission
$user->hasRolePermission('edit-post');
$user->hasRolePermission('edit-post', $scope);

// All required
$user->hasRolePermissions(['edit-post', 'delete-post']);

// Any of these
$user->hasAnyRolePermission('edit-post');
$user->hasAnyRolePermissions(['edit-post', 'delete-post']);
```

---

Query Scopes
------------

[](#query-scopes)

Filter actors by their permissions:

```
// Users with a specific permission (direct or via role)
$users = User::withPermission('edit-post')->get();
$users = User::withPermission('edit-post', $office)->get();

// Users with any of these permissions
$users = User::withAnyPermission(['edit-post', 'delete-post'])->get();

// Users with all of these permissions
$users = User::withAllPermissions(['edit-post', 'delete-post'])->get();
```

These scopes automatically include implied permissions.

---

Advanced
--------

[](#advanced)

### Permission Query Builder

[](#permission-query-builder)

Query registered permissions:

```
// Get all permissions
$allPermissions = Permission::all();

// Get by handle
$permission = Permission::get('edit-post');

// Check existence
Permission::exists('edit-post');

// Check if allowed for actor/scope
Permission::isAllowedFor('edit-post', 'user', 'office');
```

#### Filtering permissions

[](#filtering-permissions)

```
$permissions = Permission::query()
    ->where('actor_type', 'user')
    ->where('scope_type', 'office')
    ->get();

// Alternative methods
$permissions = Permission::query()
    ->whereActorType('user')
    ->whereScopeType('office')
    ->get();

// Get as options array [handle => label]
$options = Permission::query()
    ->whereActorType('user')
    ->options();

// Pluck specific fields
$options = Permission::query()
    ->where('actor_type', 'user')
    ->pluck('label', 'handle')
    ->toArray();

// Filter by multiple handles
$permissions = Permission::query()
    ->where('handle', ['edit-post', 'delete-post'])
    ->get();

// Get first match
$permission = Permission::query()
    ->whereActorType('user')
    ->first();

// Short form syntax
$permissions = Permission::where('actor_type', 'user')
    ->where('scope_type', 'office')
    ->get();

$permission = Permission::where('actor_type', 'user')->first();
```

### Multi-tenancy

[](#multi-tenancy)

The `tenant()` method scopes role operations to a specific tenant:

```
$tenant = Group::find(1);

Roles::query()
    ->roles($roles)
    ->for($user)
    ->on($office)
    ->tenant($tenant)
    ->assign();
```

During assignment, an `InvalidArgumentException` is thrown if any role does not belong to the specified tenant.

### Deleting Roles

[](#deleting-roles)

```
$role = Role::find($roleId);
$role->delete();
```

Make sure to detach any assignments or permissions related to this role before deleting to maintain data integrity.

---

Translation Support
-------------------

[](#translation-support)

Roles support multilingual translations without external packages:

```
// Get translated name (uses current locale)
echo $role->name;

// Get specific locale with fallback
$name = $role->getTranslation('name', 'es', 'Default Name');

// Set translation
$role->setTranslation('name', 'fr', 'Nom en Français');
$role->save();
```

---

Testing
-------

[](#testing)

Run the package tests with:

```
./vendor/bin/phpunit

```

Contributing
------------

[](#contributing)

Contributions are welcome! Please fork the repo, add tests, and submit a PR.

License
-------

[](#license)

Larallow is open-sourced software licensed under the [MIT license](LICENSE.md).

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance69

Regular maintenance activity

Popularity33

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

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

Recently: every ~42 days

Total

22

Last Release

173d ago

Major Versions

0.9.7 → 1.02025-08-21

### Community

Maintainers

![](https://www.gravatar.com/avatar/6a3c47449dfb2ec121aa410da024f47586b87cc2799a825f0418e6c5e5904955?d=identicon)[edulazaro](/maintainers/edulazaro)

---

Top Contributors

[![edulazaro](https://avatars.githubusercontent.com/u/7797530?v=4)](https://github.com/edulazaro "edulazaro (27 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/edulazaro-larallow/health.svg)

```
[![Health](https://phpackages.com/badges/edulazaro-larallow/health.svg)](https://phpackages.com/packages/edulazaro-larallow)
```

###  Alternatives

[lab404/laravel-impersonate

Laravel Impersonate is a plugin that allows to you to authenticate as your users.

2.3k16.4M48](/packages/lab404-laravel-impersonate)[metrogistics/laravel-azure-ad-oauth

Provides single-sign-on ability to Microsoft Azure Active Directory enabled apps.

8679.1k1](/packages/metrogistics-laravel-azure-ad-oauth)[truckersmp/steam-socialite

Laravel Socialite provider for Steam OpenID.

1516.7k](/packages/truckersmp-steam-socialite)

PHPackages © 2026

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