Advanced

Teams

Scope roles and permissions per team or tenant.

Enable teams before running the migrations (or choose it in node ace configure --teams):

config/permissions.ts
defineConfig({
  // ...
  teams: true,
  teamForeignKey: 'team_id',
})

Roles and the pivot tables get a nullable team_id column. A null team means "global".

Selecting the team

Per call, using forTeam():

await user.forTeam(teamId).assignRole('admin')
await user.forTeam(teamId).can('manage billing')
await user.forTeam(null).hasRole('admin') // global scope

Or for a whole async scope, e.g. in a middleware:

import { runWithTeam } from '@eienjs/adonisjs-permission'

await runWithTeam(teamId, async () => {
  await user.assignRole('admin')
  await user.can('manage billing')
})

Or set it for the current execution context:

import { getPermissionsTeamId, setPermissionsTeamId } from '@eienjs/adonisjs-permission'

setPermissionsTeamId(teamId)
getPermissionsTeamId()

runWithTeam uses AsyncLocalStorage, so concurrent requests never leak their team into each other.

Team ids can be numbers, bigints or UUID strings.