PHPackages                             boone-studios/laravel-scoped-roles - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. boone-studios/laravel-scoped-roles

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

boone-studios/laravel-scoped-roles
==================================

Code-defined, scope-aware RBAC for multi-tenant Laravel apps — no permission database tables required.

v0.1.1(1mo ago)052↓73.9%1MITPHPPHP ^8.2

Since Jul 11Pushed 1mo agoCompare

[ Source](https://github.com/boone-studios/laravel-scoped-roles)[ Packagist](https://packagist.org/packages/boone-studios/laravel-scoped-roles)[ RSS](/packages/boone-studios-laravel-scoped-roles/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (7)Versions (3)Used By (1)

boone-studios/laravel-scoped-roles
==================================

[](#boone-studioslaravel-scoped-roles)

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![Used by Forgebit](https://camo.githubusercontent.com/187290bd460f372218fece58ee3e7bbb592808bc411bd6a4aa22170503c5a496/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7573656425323062792d466f7267656269742d616d626572)](https://forgebit.io)

Code-defined, scope-aware RBAC for multi-tenant Laravel apps — **no permission database tables**.

Roles live in a backed enum. Permissions are a static matrix. Membership is a string on your pivot. One gate covers dashboard users and API tokens.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 12 or 13

Installation
------------

[](#installation)

```
composer require boone-studios/laravel-scoped-roles
```

Publish the config:

```
php artisan vendor:publish --tag=scoped-roles-config
```

Quick start
-----------

[](#quick-start)

1. Create a role enum that implements `BooneStudios\ScopedRoles\Contracts\DefinesPermissions`.
2. Implement `ResolvesScopedRole` (how to read the stored role string) and `ResolvesPermissionScope` (current tenant).
3. Optionally bind a `TokenPermissionResolver` for API keys.
4. Configure `config/scoped-roles.php`.

```
Gate::authorize('scoped-permission', ['manage_users']);
```

Middleware alias: `scoped.permission:manage_users`.

Inertia / Vue
-------------

[](#inertia--vue)

```
php artisan vendor:publish --tag=scoped-roles-js
```

Share `auth.role`, `auth.roleLabel`, and `auth.permissions` from your Inertia middleware, then:

```
import { usePermissions } from '@/vendor/boone-studios/usePermissions'

const { can, canAny, role } = usePermissions()
```

Cache invalidation
------------------

[](#cache-invalidation)

Resolved roles are cached per user + scope for **60 minutes by default**(`config('scoped-roles.cache_ttl_minutes')`, env `SCOPED_ROLES_CACHE_TTL`). The cache is automatically cleared on `Login` and `Logout` (see `ClearCachedScopedRoles`), but **not** on anything else — this package has no way to know when your application assigns, revokes, or changes a user's role mid-session.

**If your app changes a user's role while they may still have an active session or a cached gate check in flight, you MUST manually invalidate the cache** by calling one of:

- `ScopedRoleChecker::clearCachedRole(Authenticatable $user, Model $scope)` — clears the cached role for one user in one scope.
- `ScopedRoleChecker::clearCachedRolesForUser(Authenticatable $user, ResolvesScopedRole $roleResolver)` — clears the cached role for one user across every scope they belong to.

Otherwise the user (or their token) will keep acting under their old role for up to the full TTL.

### Example: invalidating on role assignment

[](#example-invalidating-on-role-assignment)

```
use BooneStudios\ScopedRoles\ScopedRoleChecker;

class MembershipService
{
    public function __construct(
        private \BooneStudios\ScopedRoles\Contracts\ResolvesScopedRole $roleResolver,
    ) {}

    public function assignRole(User $user, Organization $organization, string $role): void
    {
        $user->memberships()->updateOrCreate(
            ['organization_id' => $organization->id],
            ['role' => $role],
        );

        // Without this, the user (and any middleware/gate checks for them)
        // keeps seeing the previously cached role for up to cache_ttl_minutes.
        ScopedRoleChecker::clearCachedRole($user, $organization);
    }

    public function revokeAllRoles(User $user): void
    {
        $user->memberships()->delete();

        ScopedRoleChecker::clearCachedRolesForUser($user, $this->roleResolver);
    }
}
```

Differentiator
--------------

[](#differentiator)

Unlike Spatie Permission / Bouncer, this package never stores permissions in the database. The matrix is code, reviewable, and identical across environments — ideal for multi-tenant SaaS APIs.

License
-------

[](#license)

MIT © Boone Studios, LLC

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

50d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/76f1c4c8777cc7686e9ccd81c8f8deed5c4f443d7ca85cb4b78984acba7dd31c?d=identicon)[boonestudios](/maintainers/boonestudios)

---

Top Contributors

[![leemcd56](https://avatars.githubusercontent.com/u/1885663?v=4)](https://github.com/leemcd56 "leemcd56 (4 commits)")

---

Tags

laravelrolespermissionsrbacmulti-tenantscoped

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/boone-studios-laravel-scoped-roles/health.svg)

```
[![Health](https://phpackages.com/badges/boone-studios-laravel-scoped-roles/health.svg)](https://phpackages.com/packages/boone-studios-laravel-scoped-roles)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

13.0k113.1M1.7k](/packages/spatie-laravel-permission)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k17.6M166](/packages/laravel-pulse)[hasinhayder/tyro

Tyro - The ultimate Authentication, Authorization, and Role &amp; Privilege Management solution for Laravel 12 &amp; 13

6796.8k8](/packages/hasinhayder-tyro)[psalm/plugin-laravel

Psalm plugin for Laravel

3365.5M359](/packages/psalm-plugin-laravel)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

1.0k2.5M153](/packages/roots-acorn)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k161.4k2](/packages/mike-bronner-laravel-model-caching)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
