Packstub

Packstub Teams

Invite the team. Roles per tenant.

Packstub Teams is a premium plugin that gives your Filament v5 tenants everything a SaaS needs around its members: a Members page, e-mail and shareable-link invitations that walk guests through login or registration and drop them into the right team with the right role, seat limits driven by the plan, ownership rules, and roles that carry permissions — from a simple config list or from Filament Shield, per team. Filament's built-in tenancy and Filament Tenancy (database per tenant) are both supported out of the box.

Full documentation

Every guide — installation, members, invitations, roles and permissions, Shield, Filament Tenancy, configuration, testing — lives at packstub.dev/docs/filament-teams.

Features

  • Members page: managers invite, change roles and remove members; owners transfer ownership; anyone can leave.
  • Invitations: e-mail invitations and shareable links; guests sign in or register and land in the team.
  • Seat limits: from config or the plan, pending invitations counted, the invite button off when the team is full.
  • Roles and permissions: roles that carry permissions, checked with hasTeamPermission(), @teamcan or team.can:.
  • Filament Shield: Shield's roles per team, synced for each member and answered by $user->can().
  • Ownership rules: the owner role is never assigned by hand, and the last owner stays.
  • Personal teams: an optional team for every new registration.
  • Filament Tenancy preset: useFilamentTenancy() reuses its pivot, string ids and the central connection.
  • Built to extend: a Teams service that works without the traits, events, typed exceptions, translations and a prune command.

Screenshots

Members — roles per member, seats in the subheading, manager actions per row

Invite — several addresses at once with a role

Invitations — pending e-mails and shareable links, resend and revoke

Registration through an invitation — the invited e-mail is prefilled and locked

Shield roles per team — the same user is an owner in one team and a viewer in another

Installation

Requirements

Package Filament Laravel PHP
1.x ^5.0 ^12.0 / ^13.0 8.3+

Optional: spatie/laravel-permission + bezhansalleh/filament-shield for Shield-managed roles; packstub/filament-tenancy for database-per-tenant apps.

Purchasing a license

Licenses are sold at packstub.dev/plugins/filament-teams. After purchase, sign in to your Packstub dashboard and create an access token on the Install Guide page — it shows the commands below with your token filled in.

Installing with Composer

composer config repositories.packstub-filament-teams composer https://packstub.dev/composer/filament-teams
composer config --auth http-basic.packstub.dev pkg_xxxxxxxxxxxxxxxx your-token-secret
composer require packstub/filament-teams
php artisan packstub-teams:install

Full walkthrough: Installation →

Getting started

Two traits and one plugin call:

// app/Models/User.php
class User extends Authenticatable implements FilamentUser, HasTenants
{
    use HasTeamMemberships;   // joinedTeams(), teamRole(), hasTeamPermission(), getTenants(), canAccessTenant()
}

// app/Models/Team.php
class Team extends Model
{
    use HasTeamMembers;       // members(), owners(), invitations(), seatsUsed()
}

// app/Providers/Filament/AppPanelProvider.php
$panel
    ->tenant(Team::class, slugAttribute: 'slug')
    ->registration(\Packstub\Teams\Filament\Pages\Auth\Register::class)
    ->plugin(TeamsPlugin::make()->seatLimit(fn (Team $team) => $team->plan?->seats));

Make the creator of a team its owner — Teams::addMember($team, $user, Teams::ownerRole()) — and the Members and Invitations pages are live.

Roles and permissions

TeamsPlugin::make()->roles([
    'owner'  => ['label' => 'Owner', 'permissions' => ['*']],
    'admin'  => ['label' => 'Admin', 'permissions' => ['create', 'read', 'update', 'delete']],
    'editor' => ['label' => 'Editor', 'permissions' => ['create', 'read', 'update']],
    'viewer' => 'Viewer',
], default: 'viewer', managers: ['admin']);

$user->hasTeamPermission($team, 'update');
Route::get('/reports', ...)->middleware('team.can:reports.view');
@teamcan('update') <x-filament::button>Edit</x-filament::button> @endteamcan

Using Filament Shield? Enable Spatie's teams feature and the same calls are answered by Shield's roles for the current team — nothing else to wire. Filament Shield →

Invitations

Teams::invite($team, 'jane@acme.test', 'editor', inviter: $user);
Teams::inviteMany($team, ['jane@acme.test', 'sam@acme.test'], 'viewer', $user);
Teams::createInviteLink($team, 'viewer', maxUses: 10, expiresAt: now()->addWeek());

Links land on /{panel}/invitations/{token}; guests are sent through login or registration and join as soon as they sign in. Invitations →

Filament Tenancy

$panel->plugins([
    TenancyPlugin::make(),
    TeamsPlugin::make()->useFilamentTenancy(),   // tenant_user pivot, string ids, central connection
]);

Using it with Filament Tenancy →

Testing

The package ships 50+ Pest tests — membership rules, the invitation HTTP flow, Livewire page tests, the Spatie/Shield provider, string-keyed tenants — and its demo app runs Playwright end-to-end tests of the whole invite → register → join flow. Your own tests go through the Teams service, no HTTP needed. Testing →

Documentation

Guide What's inside
Installation Registry auth, installer, models, panel wiring
Members Roles, seats, ownership, who may manage
Invitations E-mail and link invitations, acceptance flow, housekeeping
Roles and permissions Role definitions, checks, providers
Filament Shield Spatie teams, per-team roles, template roles
Filament Tenancy The database-per-tenant preset
Configuration Every config key, the plugin API, the service
Testing Testing your own membership flows

Support

Changelog

Every release is documented in the package CHANGELOG.md. Config keys, the fluent API, and published views are treated as public API and follow semver.

License

Packstub Teams is commercial software. Every license includes the full source code, 12 months of updates and support, and a perpetual license for the versions you received.