NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Permissions for Laravel

Custom models & tables

Both models are non-final and resolved through config everywhere — never by a hard-coded class name. Extend them to add your own relations, scopes or casts:

namespace App\Models;

use RoundlyConsulting\Permissions\Models\Role as BaseRole;

class Role extends BaseRole
{
    // your own relations, scopes, casts …
}
// config/permissions.php
'models' => [
    'role' => App\Models\Role::class,
    'permission' => App\Models\Permission::class,
],

Permissions::role(), Permissions::permission(), every grant and every relation then use your class. Because rows are created as your class, your model events and observers fire — and the package’s cache invalidation hooks onto your model too:

use RoundlyConsulting\Permissions\Facades\Permissions;

$role = Permissions::role('editor');  // an App\Models\Role instance
Permissions::roleModel();             // App\Models\Role::class
Permissions::roleModel()::query();    // a query on your class
$user->roles;                         // Collection<App\Models\Role>

A configured class must be the packaged Role or Permission or a subclass of it. Anything else — an Eloquent model that does not extend it, or a value that is not a model at all — throws InvalidConfigurationException naming the key; it is never silently replaced by the packaged model.

Table names

Rename any table in table_names before you migrate — column names are fixed:

// config/permissions.php
'table_names' => [
    'roles' => 'acl_roles',
    'permissions' => 'acl_permissions',
    'permission_role' => 'acl_permission_role',
    'model_roles' => 'acl_model_roles',
    'model_permissions' => 'acl_model_permissions',
],

Resolving the setup in code

For the model classes, Permissions::roleModel() and permissionModel() are enough. The static resolvers on PermissionRegistrar also expose the resolved tables and key type — the published migrations call them, and so can your raw queries and own migrations:

use RoundlyConsulting\Permissions\Support\PermissionRegistrar;

PermissionRegistrar::roleModel();              // configured Role class-string
PermissionRegistrar::permissionModel();        // configured Permission class-string

PermissionRegistrar::rolesTable();             // resolved table names
PermissionRegistrar::permissionsTable();
PermissionRegistrar::permissionRoleTable();
PermissionRegistrar::modelRolesTable();
PermissionRegistrar::modelPermissionsTable();

PermissionRegistrar::keyType();                // KeyType enum — BigInt, Uuid or Ulid

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

By donating, you agree to our donation terms.

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.