jftecnologia / laravel-permission
RBAC + scoped permissions (all/self/attached) for Laravel
Package info
github.com/jftecnologia/laravel-permission
pkg:composer/jftecnologia/laravel-permission
Requires
- php: ^8.4
- illuminate/auth: ^12.0
- illuminate/contracts: ^12.0
- illuminate/database: ^12.0
- illuminate/support: ^12.0
Requires (Dev)
- driftingly/rector-laravel: ^2.1
- larastan/larastan: ^3.0
- laravel/framework: ^12.0
- laravel/pint: ^1.27
- laravel/prompts: ^0.3.9
- orchestra/testbench: ^10.8
- pestphp/pest: ^4.3
This package is auto-updated.
Last update: 2026-03-06 15:19:13 UTC
README
RBAC for Laravel with scoped permissions (all, self, attached) and optional multi-tenancy support.
1:1 model: the Gate ability string equals the permission name (e.g.
companies.edit.attached==permissions.name).
Features
- Scoped permissions with
all,self, andattachedscopes - Roles and permissions with a familiar API
- Attachment-based access for fine-grained authorization
- Optional multi-tenancy via a feature flag
- Configurable resolvers for tenant and self resolution
Installation
composer require jftecnologia/laravel-permission
Publish config (optional):
php artisan vendor:publish --tag="permission-config"
Run the migrations:
php artisan migrate
Configuration
config/permission.php:
models.permission|role|attachment: swap the Eloquent modelstables.*: rename tablestenancy.enabled: feature flag for multi-tenancy (default:true)tenancy.column: tenant column name (default:tenant_id)tenant_resolver: callback to resolve the current tenant id (nullable)self_resolver: callback to define what "self" means
Default self
If you don't define self_resolver, the package uses the convention:
resource->created_by == user->id
Usage
1) On your User model
Add the trait:
use JuniorFontenele\LaravelPermission\Traits\InteractsWithPermissions; class User extends Authenticatable { use InteractsWithPermissions; }
2) Create and assign permissions
Permissions are unique strings (permissions.name is unique):
$user->givePermissionTo('companies.edit.all');
3) Roles
$user->assignRole('editor'); $user->syncRoles(['editor', 'viewer']); $user->removeRole('viewer');
Permission via role:
$role = \JuniorFontenele\LaravelPermission\Models\Role::query()->firstOrCreate([ 'tenant_id' => null, 'name' => 'editor', 'guard_name' => 'web', ]); $role->givePermissionTo('companies.edit.all');
4) Gate/Policies (scopes)
$user->can('companies.edit.all'); $user->can('companies.edit.self', $company); $user->can('companies.edit.attached', $company);
all: checks RBAC onlyself: RBAC +self_resolverattached: RBAC +permission_attachmentsrecord
5) Attachments (attached scope)
use JuniorFontenele\LaravelPermission\Facades\Permission; Permission::attach($user, 'companies.edit.attached', $company); $user->can('companies.edit.attached', $company); // true
Multi-tenancy
Multi-tenancy support is a feature flag:
permission.tenancy.enabled = true: creates/uses tenant column in tables (migrations + queries)permission.tenancy.enabled = false: ignores tenant entirely and does not create the column
The column is configurable via permission.tenancy.column (default: tenant_id).
To enable tenant scoping, define permission.tenant_resolver in config (or pass tenantId explicitly in APIs).
Testing
composer test
Credits
License
MIT License. See LICENSE.md for details.