Skip to main content

Required Interfaces

The User model must implement three interfaces for Filament multi-tenancy:
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasDefaultTenant;
use Filament\Models\Contracts\HasTenants;

class User extends Authenticatable implements FilamentUser, HasTenants, HasDefaultTenant
{
    // ...
}

Required Methods

1. getTenants()

Returns all teams the user can access:
public function getTenants(Panel $panel): array|Collection
{
    return $this->allTeams();
}

public function allTeams(): Collection
{
    return $this->teams()
        ->union($this->ownedTeams()->toBase())
        ->orderBy('created_at', 'desc')
        ->get();
}

2. canAccessTenant()

Checks if user can access a specific team:
public function canAccessTenant(Model $tenant): bool
{
    return $this->allTeams()->contains($tenant);
}

3. getDefaultTenant()

Returns the default team for the user:
public function getDefaultTenant(Panel $panel): ?Model
{
    return $this->currentTeam ?? $this->allTeams()->first();
}

4. canAccessPanel()

Controls panel access:
public function canAccessPanel(Panel $panel): bool
{
    if ($panel->getId() === 'admin') {
        return $this->hasRole('admin');
    }

    return true;
}

Relationships

Current Team

public function currentTeam(): BelongsTo
{
    return $this->belongsTo(Team::class, 'current_team_id');
}

Teams (Member of)

public function teams(): BelongsToMany
{
    return $this->belongsToMany(Team::class)
        ->withTimestamps();
}

Owned Teams

public function ownedTeams(): HasMany
{
    return $this->hasMany(Team::class, 'owner_id');
}

Complete Example

<?php

namespace App\Models;

use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasDefaultTenant;
use Filament\Models\Contracts\HasTenants;
use Filament\Panel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser, HasTenants, HasDefaultTenant
{
    public function getTenants(Panel $panel): array|Collection
    {
        return $this->allTeams();
    }

    public function canAccessTenant(Model $tenant): bool
    {
        return $this->allTeams()->contains($tenant);
    }

    public function getDefaultTenant(Panel $panel): ?Model
    {
        return $this->currentTeam ?? $this->allTeams()->first();
    }

    public function canAccessPanel(Panel $panel): bool
    {
        if ($panel->getId() === 'admin') {
            return $this->hasRole('admin');
        }

        return true;
    }

    public function allTeams(): Collection
    {
        return $this->teams()
            ->union($this->ownedTeams()->toBase())
            ->orderBy('created_at', 'desc')
            ->get();
    }

    public function teams(): BelongsToMany
    {
        return $this->belongsToMany(Team::class)
            ->withTimestamps();
    }

    public function ownedTeams(): HasMany
    {
        return $this->hasMany(Team::class, 'owner_id');
    }

    public function currentTeam(): BelongsTo
    {
        return $this->belongsTo(Team::class, 'current_team_id');
    }
}