Grant: Enum-Based Roles &amp; Permissions for Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://msaied.com) - [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [About](https://msaied.com#about)

           [  Contact](https://msaied.com#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://msaied.com)
- [ProjectsCase studies](https://msaied.com/projects)
- [ArticlesEngineering notes](https://msaied.com/articles)
- [CertificatesCredentials](https://msaied.com/certificates)
- [AboutHow I work](https://msaied.com#about)
- [ContactGet in touch](https://msaied.com#contact)

  [Start a conversation](https://msaied.com#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://msaied.com)
2. /
3. [Articles](https://msaied.com/articles)
4. /
5. [Laravel](https://msaied.com/articles?category=laravel)
6. /
7. Grant: Enum-Based Roles and Permissions for Laravel

   [Laravel](https://msaied.com/articles?category=laravel) [Composer Pacakge](https://msaied.com/articles?category=composer-pacakge) 

 Grant: Enum-Based Roles and Permissions for Laravel
====================================================

 Grant is a Laravel package that lets you define roles and permissions as PHP enums, stores assignments in the database, and routes all checks through Laravel's Gate so can(), Gate::authorize(), and @can work out of the box.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://msaied.com#person) Published 5 Oct 2026 · Updated 6 Oct 2026 · 3 min read

ShareCopy linkCopied

 ![Grant: Enum-Based Roles and Permissions for Laravel](https://cdn.msaied.com/746/496c70db85d5a374cca5e7f9c0a182a8.png) 

  On this page +1. [Grant: Enum-Based Roles and Permissions for Laravel](#grant-enum-based-roles-and-permissions-for-laravel)
2. [Defining Roles and Permissions as Enums](#defining-roles-and-permissions-as-enums)
3. [Global and Scoped Role Assignments](#global-and-scoped-role-assignments)
4. [Combining Permissions with Policies](#combining-permissions-with-policies)
5. [Installation](#installation)
6. [Key Takeaways](#key-takeaways)

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

[Grant](https://github.com/shipfastlabs/grant) is a roles and permissions package for Laravel by Pushpak Chhajed. Instead of storing permission names as plain strings in the database, you define them as PHP backed enums. The database only stores role assignments per user, and all authorization checks flow through Laravel's Gate — meaning `can()`, `Gate::authorize()`, and Blade's `@can` directive work without any changes to your existing code.

### Defining Roles and Permissions as Enums

Grant introduces two contracts: `Ability` for permissions and `Role` for roles. A permission enum implements `Ability`, with each case's backing string value registered as a Gate ability. A role enum implements `Role` and declares which permissions it grants via a `permissions()` method:

```php
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. There is no `@role` Blade directive or role middleware — you protect routes and actions using Laravel's standard authorization features.

### Global and Scoped Role Assignments

After adding the `HasRoles` trait to your user model, you manage assignments with `grant()`, `revoke()`, and `syncRoles()`. Passing an Eloquent model via the `on` parameter scopes the role to a specific team, project, or any other model:

```php
$user->grant(Role::Editor);
$user->grant(Role::Viewer, on: $team);

$user->can(Permission::EditPosts);
$user->can(Permission::ViewReports, $team);

```

When checking a scoped permission, Grant considers both the user's global roles and any roles assigned on that specific model.

### Combining Permissions with Policies

Grant does not replace policies — it complements them. The `#[Requires]` attribute lets you gate a policy method on a permission before the method's own logic runs:

```php
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 the permission check, including any model used for scoped roles. You can also designate one role as a super admin; only a globally assigned super admin bypasses Gate checks entirely.

### Installation

Grant requires PHP 8.3 or later and Laravel 12 or 13:

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

```

The install command publishes the configuration and migration, and generates starter enum files if they do not already exist. After that, add `HasRoles` to your user model.

**Important:** If you rename or remove an enum case, existing database rows referencing the old backing value become orphaned. Run `php artisan grant:sync` to remap or clean up those rows. Use `grant:list` and `grant:show` to inspect registered permissions and a user's current roles.

### Key Takeaways

- Roles and permissions are PHP backed enums — typo-proof and IDE-friendly.
- All checks go through Laravel's Gate, so no new APIs to learn.
- Scoped roles let you assign different access per team or resource.
- The `#[Requires]` attribute combines permission checks with policy logic cleanly.
- Renaming enum cases requires a `grant:sync` run to avoid orphaned assignments.
- Requires PHP 8.3+ and Laravel 12 or 13.

---

*Source: [Grant: Enum-Based Roles and Permissions for Laravel — Laravel News](https://laravel-news.com/grant-laravel-roles-permissions)*

- [laravel](https://msaied.com/articles?search=laravel)
- [authorization](https://msaied.com/articles?search=authorization)
- [roles](https://msaied.com/articles?search=roles)
- [permissions](https://msaied.com/articles?search=permissions)
- [php-enums](https://msaied.com/articles?search=php-enums)
- [package](https://msaied.com/articles?search=package)

 Frequently asked questions 
---------------------------

  Does Grant replace Laravel's built-in Gate and policies?No. Grant integrates with Laravel's Gate rather than replacing it. All permission checks use can(), Gate::authorize(), and @can as normal. Policies still handle model-level rules, and Grant's #\[Requires\] attribute can gate a policy method on a permission before the method's own logic executes.

   What happens if I rename or delete a permission or role enum case?Renaming or removing an enum case leaves any existing database rows that reference the old backing value orphaned, causing affected users to lose that role. You should run php artisan grant:sync after making such changes to remap or delete the stale rows.

   Can I scope a role to a specific team or project rather than applying it globally?Yes. When calling grant(), pass any Eloquent model via the on parameter to scope the role to that model. Permission checks that include the same model will consider both global roles and roles scoped to that model.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://msaied.com#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://msaied.com#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleSecuring Filament Plugins with Plumb: Automated Security Scoring for PHP Packages](https://msaied.com/articles/securing-filament-plugins-with-plumb-automated-security-scoring-for-php-packages) [Next articleService Container Deep Dive: Contextual Binding, Tagging, and Method Injection](https://msaied.com/articles/service-container-deep-dive-contextual-binding-tagging-and-method-injection-1)  

   On this page
-------------

1. [Grant: Enum-Based Roles and Permissions for Laravel](#grant-enum-based-roles-and-permissions-for-laravel)
2. [Defining Roles and Permissions as Enums](#defining-roles-and-permissions-as-enums)
3. [Global and Scoped Role Assignments](#global-and-scoped-role-assignments)
4. [Combining Permissions with Policies](#combining-permissions-with-policies)
5. [Installation](#installation)
6. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://msaied.com#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/747/77f5a18ff2915d631224ade73cf34aa6.png) Laravel · 3 min read### VMPal: Give Your AI Agent a Whole Computer to Work With

6 Oct 2026 ](https://msaied.com/articles/vmpal-give-your-ai-agent-a-whole-computer-to-work-with) [ ![](https://cdn.msaied.com/745/8744e1be5136b430da52e9fca3ed3964.png)  · 3 min read### Service Container Deep Dive: Contextual Binding, Tagging, and Method Injection

6 Oct 2026 ](https://msaied.com/articles/service-container-deep-dive-contextual-binding-tagging-and-method-injection-1) [ ![](https://cdn.msaied.com/743/8998fac3a41451ab3fe1588194e17a43.png) Filament · 3 min read### Securing Filament Plugins with Plumb: Automated Security Scoring for PHP Packages

5 Oct 2026 ](https://msaied.com/articles/securing-filament-plugins-with-plumb-automated-security-scoring-for-php-packages) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://msaied.com#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://msaied.com)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://msaied.com/sitemap.xml)
