Skip to content

Scopes

Scoped checks make the target object visible in the code.

php
$user->in($company)->can(Permission::UsersInvite);

There is no global current team or hidden tenant state. The scope is stored polymorphically using scope_type and scope_id, so the same package can work with a Company, Team, Workspace, or Tenant model.

Global assignments use a null scope. They are meant for platform-level access, not company membership.

What Counts as a Scope

A scope is any Eloquent model that represents a boundary for authorization:

  • Company
  • Team
  • Workspace
  • Tenant
  • Project

The package stores scope references polymorphically, so you are not locked into a single model name.

What Scopes Do Not Do

Scopes do not prove membership by themselves. Your app still owns membership, invitations, billing state, and domain rules.

For example, this role assignment says the user has Owner access in a company:

php
$user->in($company)->assignRole(CompanyRole::Owner);

It does not create a company_user row or invite the user into the company. Keep those concepts in your application models.

The optional access:scope command can generate that application layer for you, but the separation remains:

  • Generated scope tables track membership, invitations, and the user's current scope.
  • Laravel Access tables track permissions, roles, and assignments.

For example:

php
$company->users()->attach($user, ['role' => CompanyRole::Admin->value]);
$user->in($company)->assignRole(CompanyRole::Admin);

The first line is membership. The second line is authorization.

Optional Scope Scaffolding

Laravel Starter Kit Team Support

Do not use access:scope if you already enabled team support in the official Laravel starter kit (laravel new --teams). That starter kit generates its own membership, invitation, and scope-switching code. access:scope assumes a fresh app without those files and will conflict with or duplicate the starter kit's structure.

If you want Laravel Access to create that application-owned membership layer for you, run access:scope.

bash
php artisan access:scope --name=company

The command scaffolds first-party app code: a Company model, membership and invitation tables, HasCompanies, EnsureCompanyMembership, role and permission enums, invitation routes, and current-company URL defaults. The generated code is still yours to edit.

The authorization API does not change:

php
$user->in($company)->assignRole(CompanyRole::Admin);
$user->in($company)->can(Permission::UsersInvite);

Read Scaffold team scopes for the full workflow.