Text Version of the Lesson
Filament 3 comes with multi-tenancy support out of the box: the screenshot below shows how you can switch between teams/companies, see on the top-left:

This lets you quickly set up a multi-tenant application within a single database, just by configuring the panel. It even takes care of the switching between tenants for you.
Disclaimer: Tenancy is Hard.
It is important to note here that the meaning of multi-tenancy is different for everyone and that the demo in this lesson is just one of the possible implementations. It is not a one-size-fits-all solution. And the tenancy implementation also depends on your custom code more than on Filament core functionality.
Filament documentation says this:
Filament does not provide any guarantees about the security of your application. It is your responsibility to ensure that your application is secure. Please see the security section for more information.
With that said, here's our approach:
- Configure your
tenantModel. For example, Company, Organization, Team, etc. - Each User needs to have a
belongsToManyrelationship with that Tenant model. In other words, user may belong to many teams. - Apply the tenant to your
PanelProviderto indicate that this panel is multi-tenant. - All of your Models must contain a
tenant_idcolumn, or an alternative, likecompany_id,organization_id,team_id, etc. - You must apply global scopes to all your Models to filter the data by the current tenant. Filament handles some of this, but that makes you prone to errors. It is better to do it yourself.
- There is no multi-database support. All of your tenants will have to be in the same database. Switching between them is done by filtering the data by the current tenant, and each tenant is identified by its ID in the URL segment.
Telling Filament that Your Panel is Multi-Tenant
First, we have to create a multi-tenancy model, which in our case will be Company:
Migration
Schema::create('companies', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps();}); Schema::create('company_user', function (Blueprint $table) { $table->foreignId('company_id')->constrained(); $table->foreignId('user_id')->constrained();});
app/Models/Company.php
use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Company extends Model{ protected $fillable = [ 'name' ]; public function users(): BelongsToMany { return $this->belongsToMany(User::class); }}
Once we have our Company model, we can tell Filament that our panel is...
Povilas, I'm creating a document manager SAAS for accountants. In it I will have some Global Templates that will serve to classify the records, which must be accessed by all Tenants (Document Types, Categories) but which cannot be edited by Tenants. These are tables that can only be edited by an Admin and must not be filtered by a global scope. Can you point me to documentation that helps me achieve this?
Maybe the section about Disabling global scopes?
Thanks! I'll check this.
I have the same problem, I try to setup multi tenancy but I have some tables that are for general usage and shouldnt be scoped. Or i want (same as with claudio) that admins can view everything.
I tried adding this to the ModelResource.php:
or this:
I tried using a ApplyTenantScopes and then using something like this:
But nothing seems to work. I saw in your older documentation about Filament 2.0 a possible solution (https://laraveldaily.com/post/multi-tenancy-laravel-filament-simple) but I don't know what a good soluton for 3.0 would be.
To be perfectly honest, the way how Filament v3 Multi-Tenancy is done, personally to me, seems not perfect at the moment, so I don't have a quick answer. But will try to debug and comment with possible solutions a bit later.
Ok so with the help of Dan Harrin and the filament github codebase I found a solution, copy paste the following code in the Resource that you want to exclude from the tenant scope:
And include in the top of the same file:
use Illuminate\Database\Eloquent\Model;
You basicly override the tenantscope function and return it cleanly. I haven't found problems yet, so I think (hope) this works as intended. :)
To remove the scopes from your Resource, you can do this:
CategoryResource -> Create new method:
This will override the Query creation from Filament and return you a new instance without Tenant information. Will that work everywhere? Not sure... Filament multi-tenancy does not really support:
It is more or less designed for independant tenants to live within your application and never interact.
ps. You can technically create an admin by creatin a new panel that doesn't have tenancy applied to it. It duplicates the resources and everything else but... It should work :)