---
title: "Permissions for Laravel — docs | Roundly"
description: "Developer docs for Permissions for Laravel: roles, direct permissions, Gate and can: middleware, enums, UUID/ULID holders, caching and cleanup."
url: https://roundly-consulting.com/open-source/docs/permissions-for-laravel
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

Open source

# Permissions for Laravel

Install

`composer require roundly-consulting/permissions-for-laravel`

Requires: PHP ^8.4 · Laravel ^12.0|^13.0

[GitHub](https://github.com/roundly-consulting/permissions-for-laravel) [Packagist](https://packagist.org/packages/roundly-consulting/permissions-for-laravel) [Donate (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Patreon](https://www.patreon.com/cw/roundly)

## Overview

Native roles and permissions for Laravel. Give any Eloquent model roles and direct permissions, resolve effective permissions (direct ∪ via roles), and let Laravel’s own Gate, can: middleware and $user->can() authorize against them — without ever overriding your model policies. Single-guard, cache-backed with automatic invalidation, and additive by default, so independent modules can register their own grants safely. One Permissions facade covers the catalog and every grant, and Permissions::fake() records each write in your tests. MIT-licensed, with zero third-party runtime dependencies.

### What you get

#### Roles & direct permissions

Give any Eloquent model roles and direct grants. Effective permissions are direct ∪ via-roles, de-duplicated.

#### Native Gate integration

can: middleware, $user->can() and Gate resolve permissions out of the box — model policies keep the final say.

#### Additive by default

givePermissionTo() never strips another caller’s grants; syncPermissions() sets the exact set when you mean it.

#### Self-invalidating cache

The permission catalog is cached and flushed once every grant or role/permission change commits — Octane- and queue-safe.

#### Enums & any key type

Pass strings or backed enums everywhere and bootstrap the catalog with syncFrom(); holders may use bigint, UUID or ULID keys.

#### Facade, DI or actions

Use the Permissions facade, inject PermissionsManager or call an action; Permissions::fake() records every write for your tests.

#### Translatable descriptions

Per-locale role and permission descriptions with a deliberate, non-disclosing fallback chain.

#### Orphan-safe cleanup

forgetAllAuthorization() and pruneOrphans() stop a new record from inheriting a deleted holder’s grants.

### Documentation

#### [Installation](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/installation.md)

Install via Composer, publish the config first, then publish and run the publish-only migrations.

#### [Configuration](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/configuration.md)

Every config key and its default — models, table names, holder key type, Gate hook, description fallback and cache.

#### [Database schema & key types](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/database-schema.md)

The five tables, their fixed columns, and how key\_type types model\_id for bigint, UUID or ULID holder models.

#### [The HasRoles trait](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/has-roles.md)

Add HasRoles to any authenticatable model to give it roles, direct permissions and effective-permission resolution.

#### [The Permissions facade](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/facade.md)

Every entry point on one facade: the role and permission catalog, enum sync, per-holder grants, cache, pruning and the fake.

#### [DI and actions](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/without-facade.md)

Inject PermissionsManager instead of the facade, or call the single-purpose actions directly — with the facade-to-action map.

#### [Roles & permissions](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/roles-and-permissions.md)

Create roles and permissions idempotently through the facade, look them up, seed them safely on every deploy and read their relations.

#### [Granting permissions](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/granting-permissions.md)

Grant, revoke and sync permissions on roles or directly on a model — additive by default, authoritative when you ask.

#### [Assigning roles](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/assigning-roles.md)

Assign, remove and sync roles on any holder; permissions granted to a role flow to every model that holds it.

#### [Checking access](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/checking-access.md)

Check roles and effective permissions, list names and grants, eager-load for bulk checks, and query holders by role.

#### [Backed enums](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/enums.md)

Pass your own backed enums anywhere a role or permission name is accepted — persisted as the enum’s value.

#### [Gate & middleware](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/gate-middleware.md)

Authorize with can: middleware, $user->can() and Gate — without ever overriding your model policies.

#### [Translatable descriptions](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/descriptions.md)

Per-locale role and permission descriptions via translatable-for-laravel, with a deliberate, configurable fallback.

#### [Caching](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/caching.md)

The cached permission catalog, its after-commit invalidation, bulk-write caveats and Octane and queue-worker behaviour.

#### [Deleting holders](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/deleting-holders.md)

Stop a new record from inheriting a deleted holder’s grants — detach on delete, or prune orphaned pivot rows.

#### [Custom models & tables](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/custom-models.md)

Swap in your own Role and Permission subclasses, rename the tables, and resolve the configured setup in code.

#### [Artisan commands](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/commands.md)

Flush the permission cache, prune orphaned grant rows, and inspect the package setup with php artisan about.

#### [Exceptions](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/exceptions.md)

One exception family — PermissionException, RoleDoesNotExist and PermissionDoesNotExist — with translatable messages.

#### [Testing](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/testing.md)

Record every role and permission write with Permissions::fake() and 26 assertions, then test end-to-end with factories and HTTP.

#### [Requirements](https://roundly-consulting.com/open-source/docs/permissions-for-laravel/requirements.md)

PHP 8.4+, Laravel 12 or 13, and three Roundly packages that Composer installs for you.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source.md)
