Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

El Klo's avatar
Level 11

Advice on user roles

I'm looking for a bit of advice on how to construct my app. I'm starting a new project with laravel filament v3. I have a couple of different user roles but the main are 3 different roles. We have 2 different companies that are seperated from one another but operate in a similar fashion. I have an admin role that should see all the clients, meetings etc. for both companies. the other 2 roles are from the 2 different companies and they should only be able to see the clients, meetings etc. for their own compay. How would you construct this app?

Option 1: One admin panel with multiple user roles; Option 2: A different admin panel for each role Option 3: Implement the multi-tenancy options from filament v3.

0 likes
5 replies
LaryAI's avatar
Level 58

When constructing an application with different user roles and data visibility requirements, it's important to consider both the user experience and the maintainability of the codebase. Given your scenario with Laravel Filament v3, here's a breakdown of the options you've presented:

Option 1: One admin panel with multiple user roles This is the most common approach and is generally easier to maintain because you only have one codebase to manage. You can use Laravel's built-in authorization features, such as Gates and Policies, to control access to different resources based on the user's role. Here's a basic example of how you might set this up:

  1. Define roles in your User model:
const ROLE_ADMIN = 'admin';
const ROLE_COMPANY_ONE = 'company_one';
const ROLE_COMPANY_TWO = 'company_two';

public function isAdmin()
{
    return $this->role === self::ROLE_ADMIN;
}

public function isCompanyOne()
{
    return $this->role === self::ROLE_COMPANY_ONE;
}

public function isCompanyTwo()
{
    return $this->role === self::ROLE_COMPANY_TWO;
}
  1. Use middleware to restrict access to routes:
// In a routes file
Route::middleware(['can:manage,App\Models\Client'])->group(function () {
    // Define routes that require the 'manage' ability
});
  1. Define Gates or Policies to authorize actions:
// In AuthServiceProvider or a dedicated policy class

Gate::define('manage', function ($user, $model) {
    if ($user->isAdmin()) {
        return true;
    }

    if ($user->isCompanyOne() && $model->company_id === $user->company_id) {
        return true;
    }

    if ($user->isCompanyTwo() && $model->company_id === $user->company_id) {
        return true;
    }

    return false;
});

Option 2: A different admin panel for each role This approach can be useful if the companies are very different and require completely separate panels with distinct features. However, it can lead to code duplication and can be harder to maintain. Unless there's a compelling reason to completely separate the admin panels, I would generally recommend against this approach.

Option 3: Implement the multi-tenancy options from Filament v3 If the two companies operate as separate tenants, using multi-tenancy can be a good solution. This would isolate the data for each company and ensure that users from one company cannot access data from the other. Filament v3's multi-tenancy features can help you set this up. Here's a high-level overview:

  1. Set up a tenant model and configure Filament to use it:
// In a service provider or a dedicated Filament configuration file

Filament::serving(function () {
    Filament::auth(function () {
        return Auth::user()->hasAccessToCurrentTenant();
    });
});
  1. Ensure that each user is associated with a tenant and can only access data from that tenant.

  2. Use Filament's features to scope data to the current tenant automatically.

In conclusion, for most cases, Option 1 is the most straightforward and maintainable solution. It allows you to have a single admin panel with role-based access control. If your companies' data must be strictly isolated, consider Option 3 with multi-tenancy. Option 2 should generally be avoided unless there are very specific requirements that necessitate completely separate admin panels.

1 like
vincent15000's avatar

According to me, multi-tenancy is only interesting if each company is really totally isolated from the others and have to manage its own datas.

Having one admin panel per role is interesting only if you have very different admin panels for each role.

1 like
martinbean's avatar

@el klo This doesn’t really sound like something roles would be suitable for. It just sounds like simple resource ownership, where models are “owned” by another model (in this case, a company).

So if companies have different URLs, i.e. example.com/company-1 and example.com/company-2, then you could just list records for the current company, i.e. example.com/company-1/meetings would only show meetings for that particular company:

Route::prefix('{company:slug}')->group(function () {
    Route::get('meetings', [MeetingController::class, 'index');
    Route::get('meetings/{meeting}', [MeetingController::class, 'show');
});
class MeetingController extends Controller
{
    public function index(Company $company)
    {
        $meetings = $company->meetings()->get();

        return view('company.meetings.index', compact('company', 'meetings'));
    }

    public function show(Company $company, Meeting $meeting)
    {
        return view('company.meetings.show', compact('company', 'meeting'));
    }
}
2 likes
El Klo's avatar
Level 11

@martinbean Yeah, this is kind of how multi-tenancy on laravel filament works. I have a slight preference for that option right now. Thank you.

2 likes

Please or to participate in this conversation.