Laravel Packages

Grant: Enum-Based Roles and Permissions for Laravel

Published
Grant: Enum-Based Roles and Permissions for Laravel image

Grant is a roles and permissions package for Laravel by Pushpak Chhajed. You define roles and permissions in PHP enums, while the database stores each user's role assignments. Checks go through Laravel's Gate, so existing calls to can(), Gate::authorize(), and Blade's @can work with Grant.

Define access in enums

A permission enum implements Grant's Ability contract, with each backing value registered as an ability in Laravel's Gate. A role enum implements the Role contract and lists the permissions it grants:

use Shipfastlabs\Grant\Ability;
use Shipfastlabs\Grant\Role as RoleContract;
 
enum Permission: string implements Ability
{
case EditPosts = 'edit-posts';
case ViewReports = 'view-reports';
 
public function deniedMessage(): string
{
return 'You are not allowed to do that.';
}
}
 
enum Role: string implements RoleContract
{
case Editor = 'editor';
case Viewer = 'viewer';
 
public function permissions(): array
{
return match ($this) {
self::Editor => [Permission::EditPosts],
self::Viewer => [Permission::ViewReports],
};
}
}

Grant uses roles for assignment and permissions for checks. It has no role middleware or @role directive; routes use Laravel's authorization features to check a permission. If you want more background on defining abilities in code, see our article on authorization with backed enums.

Assign global or scoped roles

After adding Grant's HasRoles trait to the user model, you can manage assignments with grant(), revoke(), and syncRoles(). Passing an Eloquent model as on scopes a role to that team, project, or other model:

$user->grant(Role::Editor);
$user->grant(Role::Viewer, on: $team);
 
$user->can(Permission::EditPosts);
$user->can(Permission::ViewReports, $team);

A scoped permission check includes the user's global roles as well as roles assigned on that model. For another approach to scoped permissions, see Larallow.

Combine permissions with policies

Policies can still handle model rules such as ownership. Grant's Requires attribute checks the permission before the policy method runs, leaving the method to check the post itself:

use Shipfastlabs\Grant\Requires;
 
#[Requires(Permission::EditPosts)]
public function update(User $user, Post $post): bool
{
return $post->author_id === $user->id;
}

Grant forwards Gate arguments to this check, including a model used for scoped roles. You can also configure one role as a super admin; only a globally assigned super admin role bypasses Gate checks.

Install and maintain roles

Grant requires PHP 8.3 or later and Laravel 12 or 13. The install command publishes its configuration and migration, and creates starter role and permission enums if they do not exist:

composer require shipfastlabs/grant
php artisan grant:install
php artisan migrate

After installation, add Shipfastlabs\Grant\HasRoles to the user model. Changing a role's backing value or deleting a case leaves its old assignments orphaned, which means those users lose the role until you remap the rows. Run php artisan grant:sync to remap or delete them; grant:list and grant:show help inspect registered permissions and a user's roles.

See the Grant repository for configuration, testing helpers, and examples of scoped roles.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Sponsored

laravelcloud logo
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud

The latest

View all →
Pollora: Run WordPress Inside a Laravel Application image

Pollora: Run WordPress Inside a Laravel Application

Read article
Scheduled Session Garbage Collection in Laravel 13.39 image

Scheduled Session Garbage Collection in Laravel 13.39

Read article
Deferred Schema Loading in Filament v5.8 image

Deferred Schema Loading in Filament v5.8

Read article
Sloppy: Static Analysis for AI-Written PHP image

Sloppy: Static Analysis for AI-Written PHP

Read article
Mastering Laravel Testing: A Video Course on Laravel Tests image

Mastering Laravel Testing: A Video Course on Laravel Tests

Read article
NativePHP Mobile Security Advisories: Update to 4.6.1 image

NativePHP Mobile Security Advisories: Update to 4.6.1

Read article