Configuration
config/access.php controls all package behavior. Below is the full config with every option shown.
Full Config File
<?php
use App\Enums\Permission;
use App\Enums\CompanyRole;
use App\Models\Company;
return [
/*
|--------------------------------------------------------------------------
| User Model
|--------------------------------------------------------------------------
|
| The authenticatable model that receives role and permission assignments.
| Same for both scoped and global-only setups.
|
*/
'user_model' => 'App\\Models\\User',
/*
|--------------------------------------------------------------------------
| Permission Enums
|--------------------------------------------------------------------------
|
| Backed enum classes used by `access:sync` to validate permissions.
| Same for both scoped and global-only setups.
|
*/
'permission_enums' => [
Permission::class,
],
/*
|--------------------------------------------------------------------------
| Default Scope Model
|--------------------------------------------------------------------------
|
| DIFFERENCE BETWEEN MODES:
|
| Scoped mode: Set to your scope model class (e.g., Company::class)
| Global-only: Leave as null
|
| This is used by commands like `debug:access --scope=company:1` to
| resolve scope strings. It does NOT affect authorization logic itself.
|
*/
'default_scope_model' => Company::class, // Scoped mode
// 'default_scope_model' => null, // Global-only mode
/*
|--------------------------------------------------------------------------
| Scaffolded Team Scope
|--------------------------------------------------------------------------
|
| Written by `access:scope`. This records the app-owned model and naming
| selected for generated team/company/workspace/tenant support.
|
*/
'teams' => [
'model' => Company::class,
'singular' => 'company',
'plural' => 'companies',
],
/*
|--------------------------------------------------------------------------
| Invitations
|--------------------------------------------------------------------------
|
| Used by the invitation flow generated by `access:scope`.
|
*/
'invitations' => [
'require_existing_user' => false,
'expiry_days' => 7,
'redirect_after_accept' => 'dashboard',
],
/*
|--------------------------------------------------------------------------
| Cache
|--------------------------------------------------------------------------
|
| Permission resolution caching. Same for both modes.
|
*/
'cache' => [
'enabled' => env('APP_ENV') !== 'testing',
'key' => 'access.permissions',
'ttl' => null, // null = forever until cache clear
],
/*
|--------------------------------------------------------------------------
| Scoped Roles
|--------------------------------------------------------------------------
|
| DIFFERENCE BETWEEN MODES:
|
| Scoped mode: Define roles here. Each assignment is tied to a
| specific scope model instance via in($model).
| Global-only: Leave empty [].
|
| Keys are role names. Values are arrays of Permission enum cases.
| When using `access:scope`, prefer the generated role enum values to
| keep membership roles and access roles aligned.
|
*/
'roles' => [
CompanyRole::Owner->value => [
Permission::CompanyMembersView,
Permission::CompanyMembersInvite,
Permission::CompanyMembersManage,
Permission::RolesManage,
Permission::CompanyUpdate,
],
CompanyRole::Admin->value => [
Permission::CompanyMembersView,
Permission::CompanyMembersInvite,
Permission::CompanyUpdate,
],
CompanyRole::Member->value => [
Permission::CompanyMembersView,
],
],
/*
|--------------------------------------------------------------------------
| Global Roles
|--------------------------------------------------------------------------
|
| DIFFERENCE BETWEEN MODES:
|
| Scoped mode: Use for platform-level roles that apply everywhere
| regardless of scope (e.g., "Platform Admin").
| Global-only: Define ALL your roles here. This is your primary
| role configuration.
|
| Keys are role names. Values are arrays of Permission enum cases.
|
*/
'global_roles' => [
'Platform Admin' => [
Permission::SystemManage,
],
],
/*
|--------------------------------------------------------------------------
| Gate Before Override
|--------------------------------------------------------------------------
|
| When enabled, users with the specified global role bypass ALL Laravel
| Gate and Policy checks. Same for both modes.
|
| Use with caution — this grants unrestricted access.
|
*/
'gate_before' => [
'enabled' => false,
'global_role' => 'Platform Admin',
],
];Options Reference
user_model : The authenticatable model that receives assignments. Same for both modes.
permission_enums : Backed enum classes used by access:sync. Same for both modes. access:install --enum creates App\Enums\Permission and writes it here. access:scope --name=company adds starter company permission cases to App\Enums\Permission when that file exists. Add more enum classes to this array only when you intentionally want modular permission enums.
default_scope_model : Scoped: set to your scope model class (e.g., Company::class). Global-only: leave as null. Used by dev commands to resolve scope strings like company:1. This is a model class, not a table name; the model determines its own table.
teams : Metadata for the app-owned scope generated by access:scope. The key remains teams for compatibility even when the domain term is company, workspace, tenant, or another name.
invitations : Settings for the invite flow generated by access:scope. require_existing_user controls whether brand-new users can register from an invitation, expiry_days controls default invitation lifetime, and redirect_after_accept is the named route used after a successful join.
roles : Scoped: define your per-scope roles here. Global-only: leave empty []. If access:scope generated a role enum, use enum values as keys, such as CompanyRole::Admin->value, instead of repeating raw strings.
global_roles : Scoped: optional platform-level roles that apply everywhere. Global-only: define all your roles here.
The distinction matters when seeding. roles are assigned with $user->in($scope)->assignRole(...); global_roles are assigned with $user->assignGlobalRole(...). See Seed roles and permissions for first-time and update workflows.
cache : Permission resolution caching. Same for both modes.
gate_before : Optional Laravel Gate override for a global role. Same for both modes.
Scoped Mode Quick Reference
'default_scope_model' => Company::class,
'roles' => [
CompanyRole::Owner->value => [Permission::CompanyMembersView, Permission::CompanyMembersInvite],
],
'global_roles' => [
'Platform Admin' => [Permission::SystemManage],
],$user->in($company)->assignRole(CompanyRole::Owner);
$user->in($company)->can(Permission::CompanyMembersInvite);Global-Only Mode Quick Reference
'default_scope_model' => null,
'roles' => [],
'global_roles' => [
'Admin' => [Permission::UsersView, Permission::UsersInvite],
'Viewer' => [Permission::UsersView],
],$user->assignGlobalRole('Admin');
$user->canGlobally(Permission::UsersInvite);Gate Before Override
When enabled, the configured global role can bypass Laravel Gate checks:
'gate_before' => [
'enabled' => false,
'enabled' => true,
'global_role' => 'Platform Admin',
],Use this only when platform administrators should be allowed through every Laravel policy and gate check.