Skip to content

Global versus Team Access

mozrin edited this page Nov 9, 2026 · 2 revisions

Global versus Team Access

Permission and role definitions are application-wide. Assignment scope is explicit on each grant, revoke or check. There is no mutable current team.

  • Without a team: grants, revocations and checks operate on application-wide assignments only.
  • With a team: grant requires existing active membership. A check requires membership and considers global grants plus that exact team's grants.
  • Another team's assignments never contribute. Membership alone grants nothing, including when a role's name happens to match the team name.
  • hasRole requires an actual role assignment. Equivalent direct permissions do not confer a role.
  • hasPermission considers direct grants and all permissions of roles assigned in the applicable scope.
  • Revoking a direct permission leaves role-derived access intact. Revoking a role leaves a separate direct permission intact.
  • Team-specific revocation never removes a global assignment; global revocation never removes a team assignment.
  • Removing membership deletes that member's scoped assignments. Rejoining does not restore them. Global grants remain stored, but cannot be used in a team context until membership exists again.
  • Repeated grants and membership additions are idempotent. Revoking an absent assignment or removing absent membership is safe. Unknown definitions in mutations fail clearly; unknown names in checks fail closed.
  • admin has no implicit bypass, wildcard permissions or special behavior.
$access->definePermission('documents.edit');
$access->defineRole('editor', ['documents.edit']);
$access->addMember($teamA, $user);
$access->addMember($teamB, $user);

$user->assignRole('editor', team: $teamA);
$user->hasPermission('documents.edit');               // false
$user->hasPermission('documents.edit', team: $teamA); // true
$user->hasPermission('documents.edit', team: $teamB); // false

$user->assignPermission('documents.edit');
$user->hasPermission('documents.edit', team: $teamB); // true via global grant
$user->revokeTeam($teamB);
$user->hasPermission('documents.edit', team: $teamB); // false; no membership
$user->hasPermission('documents.edit');               // true; global remains

Teams never automatically isolate application data. The host must constrain resource queries and verify a resource belongs to the explicit team before using team permissions. They are membership groups and optional authorization scopes, not a database tenancy framework. See Authorized Integration.

Clone this wiki locally