One possible solution is to use a combination of global and tenant-based roles/permissions, but with a clear hierarchy and rules for how they interact. Here's an example approach:
-
Define a set of global roles/permissions that apply to all tenants, such as "admin", "employee", "guest", etc. These roles/permissions should be managed at the global level and apply to all tenants.
-
Define a set of tenant-specific roles/permissions that apply only to a particular tenant, such as "tenant_admin", "tenant_employee", etc. These roles/permissions should be managed at the tenant level and apply only to users within that tenant.
-
Define a set of rules for how these roles/permissions interact. For example, a user with a global "admin" role should have access to all tenant-specific roles/permissions within their own tenant, but not in other tenants. Similarly, a user with a tenant-specific "tenant_admin" role should have access to all global roles/permissions, but only within their own tenant.
-
Implement these rules in your application code, using a combination of global and tenant-specific checks to determine a user's access level. For example, you might have a function that checks if a user has a particular role/permission within their own tenant, and another function that checks if they have a global role/permission.
Here's an example implementation in Laravel:
// Define global roles/permissions
Gate::define('admin', function ($user) {
return $user->isGlobalAdmin();
});
// Define tenant-specific roles/permissions
Gate::define('tenant_admin', function ($user, $tenant) {
return $user->isTenantAdmin($tenant);
});
// Check if user has a particular role/permission within their own tenant
if (Gate::forUser($user)->allows('tenant_admin', $tenant)) {
// User has tenant-specific admin access
}
// Check if user has a global role/permission
if (Gate::forUser($user)->allows('admin')) {
// User has global admin access
}
This approach allows you to have both global and tenant-specific roles/permissions, while still maintaining a clear hierarchy and rules for how they interact. It also allows you to handle use cases such as automatically assigning users to a particular tenant, restricting access to global functions, and targeting a group for mass action.