---
title: "Roles & permissions — Permissions for Laravel | Roundly"
description: "Create roles and permissions idempotently through the facade, look them up, seed them safely on every deploy and read their relations."
url: https://roundly-consulting.com/open-source/docs/permissions-for-laravel/roles-and-permissions
language: en
---

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

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

# Roles & permissions

Permissions::role() and Permissions::permission() are idempotent under the unique name index, and they create and return the model you configured at permissions.models.\* — so a host subclass gets its own class back, its own model events and its own observers. Role::findOrCreate() and Permission::findOrCreate() are sugar for the same calls:

```php
use RoundlyConsulting\Permissions\Facades\Permissions;

$role = Permissions::role('administrator');
$permission = Permissions::permission('auth.users.view');

// The same thing, from the models:
Role::findOrCreate('administrator');
Permission::findOrCreate('auth.users.view');
```

Both accept a string or a backed enum — the enum’s value becomes the name. Creation uses createOrFirst, so concurrent calls never produce a duplicate.

## Looking them up

findRole(), findPermission() and roles() are live queries; permissions() and exists() answer from the cached catalog:

```php
Permissions::findRole('administrator');        // ?Role
Permissions::findPermission('auth.users.view'); // ?Permission — the full row
Permissions::roles();                           // every role, ordered by name
Permissions::permissions();                     // the cached catalog: id + name only
Permissions::exists('auth.users.view');         // bool, from the cache
Permissions::roleModel()::query()->where(...);  // a query on your configured model
```

## Seeding

Because role() and permission() are idempotent and givePermissionTo is additive, the same seeder can run on every deploy without duplicating rows or stripping grants. To register a whole enum in one call, see Backed enums:

```php
use Illuminate\Database\Seeder;
use RoundlyConsulting\Permissions\Facades\Permissions;

final class PermissionSeeder extends Seeder
{
    public function run(): void
    {
        foreach (['auth.users.view', 'auth.users.edit', 'auth.users.delete'] as $name) {
            Permissions::permission($name);
        }

        Permissions::for(Permissions::role('editor'))
            ->givePermissionTo('auth.users.view', 'auth.users.edit');

        Permissions::for(Permissions::role('administrator'))
            ->givePermissionTo('auth.users.view', 'auth.users.edit', 'auth.users.delete');
    }
}
```

## Reading roles and permissions

```php
$role->permissions;                         // Collection<Permission> granted to the role
$role->getPermissionNames();                // Collection<string>
$role->hasPermissionTo('auth.users.view');  // bool — the role's own grants

$permission->roles;                         // Collection<Role> that carry the permission
```

## Descriptions

Both models carry an optional translatable description — a per-locale label for admin screens. See Translatable descriptions for reading and fallback rules:

```php
$role->update(['description' => ['en' => 'Administrator', 'sk' => 'Administrátor']]);
```

## 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/docs/permissions-for-laravel.md)
