A flexible multi-tenancy package for Laravel that adds workspace (team) functionality to your application. Supports workspace switching, member management, invitations, and role-based permissions.
- β¨ Features
- π¦ Installation
- βοΈ Configuration
- π Usage
- π Documentation
- π§ͺ Testing
- π Changelog
- π€ Contributing
- π Security Vulnerabilities
- π Support This Project
- π¦ Other Packages
- β Star History
- π License
β οΈ Disclaimer
- π’ Workspace Management - Create, update, and delete workspaces with soft delete support
- π₯ Member Management - Add, remove, and update member roles within workspaces
- π§ Invitation System - Email-based invitations with expiration and token-based acceptance
- π Role-Based Permissions - Flexible permission system with wildcard support
- π Context Resolution - Multiple strategies for resolving current workspace (auth, subdomain, header, session, route)
- π‘οΈ Middleware - Built-in middleware for workspace access control
- π’ Events - Comprehensive events for all workspace operations
- ποΈ Multi-Tenancy Ready - Scope models to workspaces with automatic filtering
You can install the package via composer:
composer require climactic/laravel-workspacesRun the install command to publish config and migrations:
php artisan workspaces:install
php artisan migrateThe configuration file will be published to config/workspaces.php. Key options include:
return [
// Models
'models' => [
'workspace' => \Climactic\Workspaces\Models\Workspace::class,
'membership' => \Climactic\Workspaces\Models\WorkspaceMembership::class,
'invitation' => \Climactic\Workspaces\Models\WorkspaceInvitation::class,
],
// User model
'user_model' => \App\Models\User::class,
// Roles with permissions
'roles' => [
'owner' => ['permissions' => ['*']],
'admin' => ['permissions' => ['workspace.view', 'workspace.update', 'members.*']],
'member' => ['permissions' => ['workspace.view', 'members.view']],
],
// Auto-create workspace on user registration
'auto_create_on_registration' => [
'enabled' => true,
'name_from' => 'name',
'name_suffix' => "'s Workspace",
],
];Add the HasWorkspaces trait to your User model:
use Climactic\Workspaces\Concerns\HasWorkspaces;
class User extends Authenticatable
{
use HasWorkspaces;
}// Create a workspace
$workspace = $user->createWorkspace('My Team');
// Switch to a workspace
$user->switchWorkspace($workspace);
// Get current workspace
$current = $user->currentWorkspace;
// Check membership
$user->belongsToWorkspace($workspace); // true/false
// Check permissions
$user->hasWorkspacePermission($workspace, 'members.invite'); // true/false// Simple creation
$workspace = $user->createWorkspace('Engineering Team');
// With description
$workspace = $user->createWorkspace('Engineering Team', [
'description' => 'Our engineering department',
]);
// Using the action directly
use Climactic\Workspaces\Actions\CreateWorkspace;
$workspace = app(CreateWorkspace::class)->execute(
data: ['name' => 'My Workspace', 'description' => 'A great workspace'],
owner: $user,
setAsCurrent: true
);// Switch workspace
$user->switchWorkspace($workspace);
// Check if workspace is current
$user->isCurrentWorkspace($workspace); // true/false
// Get current workspace
$current = $user->currentWorkspace;
// Get current workspace ID
$id = $user->current_workspace_id;// Add a member
$workspace->addMember($user, 'member');
// Update member role
$workspace->updateMemberRole($user, 'admin');
// Remove a member
$workspace->removeMember($user);
// Get member's role
$role = $user->workspaceRole($workspace); // 'owner', 'admin', etc.
// Check role
$user->hasWorkspaceRole($workspace, 'admin'); // true/false
$user->hasWorkspaceRole($workspace, ['admin', 'owner']); // true if any matchuse Climactic\Workspaces\Actions\CreateInvitation;
// Create an invitation
$invitation = app(CreateInvitation::class)->execute(
workspace: $workspace,
email: 'newuser@example.com',
role: 'member',
invitedBy: $currentUser
);
// Accept an invitation
use Climactic\Workspaces\Actions\AcceptInvitation;
app(AcceptInvitation::class)->execute($invitation, $user);
// Decline an invitation
use Climactic\Workspaces\Actions\DeclineInvitation;
app(DeclineInvitation::class)->execute($invitation);// Check permission
$user->hasWorkspacePermission($workspace, 'members.invite');
// Get all permissions
$permissions = $user->workspacePermissions($workspace);
// Wildcard permissions work automatically
// If role has 'members.*', it grants 'members.invite', 'members.remove', etc.// In routes/web.php
Route::middleware(['auth', 'workspace'])->group(function () {
// Routes that need workspace context
});
Route::middleware(['auth', 'workspace.access'])->group(function () {
// Routes that require workspace membership
});
Route::middleware(['auth', 'workspace.role:admin,owner'])->group(function () {
// Routes that require specific roles
});The package supports multiple strategies for resolving the current workspace:
// In config/workspaces.php
'context' => [
'resolvers' => [
\Climactic\Workspaces\ContextResolvers\AuthUserResolver::class,
\Climactic\Workspaces\ContextResolvers\SubdomainResolver::class,
\Climactic\Workspaces\ContextResolvers\RouteParameterResolver::class,
\Climactic\Workspaces\ContextResolvers\HeaderResolver::class,
\Climactic\Workspaces\ContextResolvers\SessionResolver::class,
],
],The package fires events for all major operations:
| Event | Description |
|---|---|
WorkspaceCreated |
Fired when a workspace is created |
WorkspaceDeleted |
Fired when a workspace is deleted |
WorkspaceSwitched |
Fired when a user switches workspaces |
MemberAdded |
Fired when a member is added |
MemberRemoved |
Fired when a member is removed |
MemberRoleUpdated |
Fired when a member's role is updated |
InvitationCreated |
Fired when an invitation is created |
InvitationAccepted |
Fired when an invitation is accepted |
InvitationDeclined |
Fired when an invitation is declined |
InvitationCancelled |
Fired when an invitation is cancelled |
For detailed documentation, see the docs folder:
composer testPlease see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details. You can also join our Discord server to discuss ideas and get help: Discord Invite.
Please report security vulnerabilities to security@climactic.co.
Laravel Workspaces is free and open source, built and maintained with care. If this package has saved you development time or helped power your application, please consider supporting its continued development.
Your logo here β Become a sponsor and get your logo featured in this README and on our website.
Interested in title sponsorship? Contact us at sponsors@climactic.co for premium placement and recognition.
Check out our other Laravel packages:
| Package | Description |
|---|---|
| Laravel Credits | A ledger-based Laravel package for managing credit-based systems in your application. Perfect for virtual currencies, reward points, or any credit-based feature. |
The AGPL-3.0 License. Please see License File for more information.
This package is not affiliated with Laravel. It's for Laravel but is not by Laravel. Laravel is a trademark of Taylor Otwell.