tanerkay / laravel-model-acl
Access control based on individual records / models
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/tanerkay/laravel-model-acl
Requires
- php: ^8.1
- illuminate/config: ^9.0|^10.0|^11.0|^12.0
- illuminate/database: ^9.0|^10.0|^11.0|^12.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0
- spatie/laravel-package-tools: ^1.11
Requires (Dev)
- ext-json: *
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
This package is auto-updated.
Last update: 2026-01-04 10:28:25 UTC
README
An experiment in model-based access control for Laravel applications.
This was to address a shortcoming or two I found in Laravel policies and gates, though that is no longer the case.
This package allows record-level access control based on custom authorization rules.
This handles cases where you may have many records in a table, but each entity has its own rules for access control. For example, you may have a table of documents, and it's not a simple scenario where a user can edit their own documents, and view all others. Maybe the access of each document has to be set separately, e.g. document X can be edited by Bob & Jane, and viewed by the Staff group; whereas document Y can only be viewed by the Finance team.
Here's a demo of how you can use it:
use Illuminate\Database\Eloquent\Model; use Tanerkay\ModelAcl\Traits\ModelBasedAccessControl; class Report extends Model { use ModelBasedAccessControl; // ... } $post->can('view');
Documentation
Installation
composer require tanerkay/laravel-model-acl
You can publish the migration with:
php artisan vendor:publish --provider="Tanerkay\ModelAcl\ModelAclServiceProvider" --tag="model-acl-migrations"
php artisan migrate
You can optionally publish the config file with:
php artisan vendor:publish --provider="Tanerkay\ModelAcl\ModelAclServiceProvider" --tag="model-acl-config"
Assigning access control rules to individual models
The addAccessControl() method can be used to add rules to individual models.
public function addAccessControl( string|array $abilities, object|array $ruleDefinitions, ?string $description = null ): void
It accepts:
- an ability name or list of abilities that can be used in calls to
can(). - an array of rule definitions, each rule definition is an array containing a class string
'class'and an array of arguments'arguments'. - an optional description of the rule, which can be stored in the database alongside the rule definition.
e.g. Restrict a certain post to moderators and admins.
use Tanerkay\ModelAcl\Rules\HasRole; $post->addAccessControl('view', [ [ 'class' => HasRole::class, 'arguments' => ['admin', 'moderator'], ] ]); // throws exception if $user->hasRole(['admin', 'moderator']) doesn't return true $post->can('view');
The HasRole class assumes your User model has a method hasRole() that accepts a string or an array of strings. You can customize the name of the method using the env key MODEL_ACL_AUTHENTICATABLE_HAS_ROLE.
Creating custom rules
For other rules or logic, you can construct your own Rule class which implements \Tanerkay\ModelAcl\Contracts\RuleContract or which extends the abstract class \Tanerkay\ModelAcl\Rules\Rule.
e.g.
use Illuminate\Support\Arr; use Tanerkay\ModelAcl\Rules\Rule; use Tanerkay\ModelAcl\Exceptions\AuthorizationException; class IpWhitelistRule extends Rule { public function authorize(?Authenticatable $user, $options): void { $ip = request()->ip(); $whitelist = Arr::wrap($options['ip_whitelist']); if (!in_array($ip, $whitelist)) { throw new AuthorizationException('IP address not in whitelist.'); } } }
$site = Site::query()->create(); $site->addAccessControl('show', [ [ 'class' => IpWhitelistRule::class, 'options' => [ 'ip_whitelist' => ['127.0.0.1'], ], ] ]); // throws exception if request()->ip() is not in the whitelist $site->can('show');
Testing
composer test
Thanks
- Spatie for making awesome packages, this package leverages
spatie/laravel-package-toolsand is itself derived fromspatie/laravel-activitylog.