maxiviper117/laravel-access
A Laravel package for managing user access and permissions with a simple API, helping you define abilities and control authorization across your application.
Start by installing the package and publishing its assets:
composer require maxiviper117/laravel-access
php artisan vendor:publish --provider="Maxiviper117\Access\AccessServiceProvider"
php artisan migrate
Look first at:
config/access.php (or similarly named config) for permission/role table names, cache settings, and model bindings.Permission model and any registrar/contract used for permission definitions — v0.1.10 adds dynamic permission definitions, so this is the key area for day-to-day work.A first practical use case: define a permission at runtime, assign it to a role, and protect a route.
use Maxiviper117\Access\Models\Permission;
use Maxiviper117\Access\Models\Role;
$permission = Permission::firstOrCreate(['name' => 'reports.export']);
$role = Role::firstOrCreate(['name' => 'manager']);
$role->givePermissionTo($permission);
// Route middleware or Gate check
Gate::allows('reports.export');
Because v0.1.10 supports dynamic definitions, you can register permissions from a database table, a module manifest, or tenant configuration rather than only from a static config file.
Dynamic permission registration in a service provider. Register permissions during boot from a source of truth such as a config array, database table, or discovered module manifests. Keep registration idempotent with firstOrCreate or updateOrCreate so repeated boots do not create duplicates.
public function boot()
{
foreach (config('modules.permissions', []) as $permission) {
Permission::firstOrCreate(['name' => $permission]);
}
}
Cache the permission map. Dynamic definitions often mean database lookups. Load permissions once per request or cache the name-to-ID map, then invalidate the cache when permissions change. This is especially important if you resolve permissions in middleware or policies.
Role and permission assignment in admin workflows. Use transactions when syncing roles and permissions from an admin UI. Prefer syncPermissions/syncRoles style operations where available, and guard against deleting permissions that are still assigned.
Gate integration. Register permissions as Gate abilities, or rely on the package's built-in permission checks. Use Gate::before for super-admin bypasses, policies for model-specific authorization, and Blade directives such as @can('reports.export') for UI gating.
Multi-tenant and module-based permissions. Prefix permission names (billing.invoices.view, reports.export) to avoid collisions. If the package supports teams or tenant scoping, scope permission checks and assignments by tenant ID rather than globally.
Testing. Use RefreshDatabase, seed the required permissions, and assert with actingAs($user) plus assertTrue(Gate::allows('permission')). For dynamic definitions, reset any cached registrar between tests so permission changes are visible.
Integration tip: treat the package's permission registrar as the boundary. If you need permissions from a new source (e.g. a plugin system), add a small registrar or service provider hook rather than scattering Permission::create calls throughout the app.
composer.json and review the changelog before upgrading. Expect API and schema changes before 1.0.firstOrCreate for every permission on every request. Register permissions in a deploy step, seeder, or cached bootstrapping path.view will collide quickly in a dynamic system.Gate::inspect('permission') to see the denial message, and php artisan tinker to inspect Permission::all() and role assignments. Log permission registration during boot in non-production environments.php artisan config:cache can freeze values. Prefer database or discoverable manifests for permissions that change at runtime.setUp/tearDown to keep authorization tests deterministic.How can I help you explore Laravel packages today?