PHPackages                             sepehr-mohseni/laramodutenant - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. sepehr-mohseni/laramodutenant

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

sepehr-mohseni/laramodutenant
=============================

A battle-tested modular multi-tenancy package for Laravel. Module scaffolding, tenant isolation, RBAC, unified API responses, and 45+ artisan commands.

1.0.0(3mo ago)34MITPHPPHP ^8.2

Since Mar 16Pushed 3mo agoCompare

[ Source](https://github.com/sepehr-mohseni/laramodutenant)[ Packagist](https://packagist.org/packages/sepehr-mohseni/laramodutenant)[ Docs](https://github.com/sepehr-mohseni/laramodutenant)[ RSS](/packages/sepehr-mohseni-laramodutenant/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (10)Versions (2)Used By (0)

LaraModuTenant
==============

[](#laramodutenant)

[![Latest Version on Packagist](https://camo.githubusercontent.com/b58604e804c6c531bf738fbe40578ae9b4d74ef81b6a417748bf7e34c9b34c6c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7365706568722d6d6f6873656e692f6c6172616d6f647574656e616e742e737667)](https://packagist.org/packages/sepehr-mohseni/laramodutenant)[![License](https://camo.githubusercontent.com/c62e7a662cd27be33059afe9a696bee57d2702056d684d396ca9638cd92ea2cc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7365706568722d6d6f6873656e692f6c6172616d6f647574656e616e742e737667)](https://packagist.org/packages/sepehr-mohseni/laramodutenant)

A senior-grade **modular architecture + multi-tenancy** package for Laravel 11+. Build scalable, tenant-aware applications with a powerful module system, RBAC, tenant-scoped authentication, and 45+ artisan commands — all in one package.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Architecture](#architecture)
- [Multi-Tenancy](#multi-tenancy)
- [RBAC (Role-Based Access Control)](#rbac-role-based-access-control)
- [API Response Envelope](#api-response-envelope)
- [Authentication](#authentication)
- [Artisan Commands](#artisan-commands)
- [Configuration](#configuration)
- [Customisation](#customisation)
- [Facades](#facades)
- [Testing](#testing)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Acknowledgments](#acknowledgments)
- [License](#license)

Features
--------

[](#features)

- **Modular Architecture** — Organize your application into self-contained modules, each with its own models, controllers, routes, migrations, seeders, configs, and translations.
- **Single-Database Multi-Tenancy** — Tenant isolation via a configurable column (`tenant_id`) with automatic query scoping — no separate databases needed.
- **Combined Modules + Tenancy** — The only package that natively integrates modular architecture with multi-tenancy in a single cohesive system.
- **Per-Tenant Module Toggling** — Enable or disable modules on a per-tenant basis, giving each tenant a tailored feature set.
- **Built-in RBAC** — Roles and permissions system with tenant-scoped assignment, middleware guards, and a clean trait-based API.
- **Tenant-Scoped Authentication** — Custom user provider that isolates authentication to the current tenant, preventing cross-tenant access.
- **Tenant-Scoped Sanctum Tokens** — API tokens are automatically prefixed with tenant context for full token isolation.
- **Rate-Limited AuthManager** — Ready-to-use login/logout with configurable rate limiting, tenant scoping, and token creation.
- **Unified API Response Envelope** — Consistent JSON response format (`success`, `message`, `data`, `errors`, `meta`) across your entire API.
- **API Exception Renderer** — Automatically converts exceptions into clean JSON responses for API routes.
- **Base ApiController &amp; ApiFormRequest** — Extend these for built-in response helpers and consistent validation error formatting.
- **Tenant Resolution Strategies** — Resolve tenants from `X-Tenant-ID` header, `X-Tenant-Slug` header, subdomain, or authenticated user's relation.
- **45+ Artisan Commands** — 28 module generators (`module:make-*`), 8 tenant management commands, 8 module management commands, and an install command.
- **Full Module Scaffolder** — `module:make` generates a complete module with models, controllers, requests, resources, routes, migration, seeder, config, and lang files in one command.
- **Configurable Models** — Swap the default Tenant, User, Role, and Permission models with your own implementations via config.
- **Publishable Stubs** — Customize the generated code by publishing and editing the package stubs.
- **Facades** — Clean `ModuleManager` and `TenantContext` facades for expressive, readable code.
- **Multilingual Support** — All response messages are translatable via Laravel's localization system.
- **Zero Config to Start** — Works out of the box with sensible defaults; customize only what you need.
- **Laravel 11 &amp; 12 Compatible** — Built for modern Laravel with PHP 8.2+ features and auto-discovery.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11.x or 12.x

Installation
------------

[](#installation)

```
composer require sepehr-mohseni/laramodutenant
```

The package auto-discovers its service provider. Then run the install command:

```
php artisan laramodutenant:install
```

This will:

1. Publish the config file to `config/laramodutenant.php`
2. Publish migrations for tenants, roles, and permissions tables
3. Publish translation files
4. Create the `modules/` directory with a Core module

Then run migrations:

```
php artisan migrate
```

Quick Start
-----------

[](#quick-start)

### 1. Add Traits to Your User Model

[](#1-add-traits-to-your-user-model)

```
use Sepehr_Mohseni\LaraModuTenant\Traits\BelongsToTenant;
use Sepehr_Mohseni\LaraModuTenant\Traits\HasRoles;

class User extends Authenticatable
{
    use BelongsToTenant;
    use HasRoles;

    // ...
}
```

### 2. Create a Tenant

[](#2-create-a-tenant)

```
php artisan tenant:create "Acme Corp" --modules=core,crm
```

### 3. Create a Module

[](#3-create-a-module)

```
php artisan module:make Blog --models=Post,Category,Tag
```

This scaffolds a complete module with:

- Models with `BelongsToTenant` trait
- API controllers extending `ApiController`
- Form requests extending `ApiFormRequest`
- API resources
- Routes with tenant &amp; module middleware
- Migration, seeder, config, and lang files

### 4. Create Users &amp; Roles

[](#4-create-users--roles)

```
php artisan tenant:create-user acme-corp --name="John Doe" --email=john@acme.com
php artisan tenant:create-role acme-corp admin --description="Administrator"
php artisan tenant:assign-role acme-corp john@acme.com admin
```

Architecture
------------

[](#architecture)

### Directory Structure

[](#directory-structure)

```
your-app/
├── modules/
│   ├── Core/
│   │   ├── Config/
│   │   ├── Database/Migrations/
│   │   ├── Database/Seeders/
│   │   ├── Http/Controllers/
│   │   ├── Http/Requests/
│   │   ├── Http/Resources/
│   │   ├── Models/
│   │   ├── Providers/
│   │   ├── Lang/en/
│   │   ├── Routes/
│   │   ├── Services/
│   │   └── module.json
│   ├── CRM/
│   └── Blog/
├── config/
│   └── laramodutenant.php

```

### Module JSON

[](#module-json)

Each module has a `module.json` that defines its metadata:

```
{
    "name": "Blog",
    "alias": "blog",
    "description": "Blog module",
    "order": 10,
    "enabled": true,
    "providers": [
        "Modules\\Blog\\Providers\\BlogServiceProvider"
    ]
}
```

Multi-Tenancy
-------------

[](#multi-tenancy)

LaraModuTenant uses a **single-database** multi-tenancy approach with a configurable tenant column (default: `tenant_id`).

### Tenant Resolution

[](#tenant-resolution)

The `IdentifyTenant` middleware resolves tenants from (in order):

1. `X-Tenant-ID` header
2. `X-Tenant-Slug` header
3. Subdomain
4. Authenticated user's tenant relation

### Tenant Context

[](#tenant-context)

```
use Sepehr_Mohseni\LaraModuTenant\Facades\TenantContext;

// Check if a tenant is set
TenantContext::check();

// Get the current tenant
$tenant = TenantContext::get();

// Get tenant ID
$id = TenantContext::id();
```

### Automatic Scoping

[](#automatic-scoping)

Models using the `BelongsToTenant` trait are automatically scoped:

```
// Automatically filters by current tenant
$posts = Post::all(); // WHERE tenant_id = {current_tenant_id}

// Bypass tenant scoping
$allPosts = Post::withoutTenancy()->get();
```

### Per-Tenant Module Access

[](#per-tenant-module-access)

```
// Enable/disable modules per tenant
$tenant->enableModule('blog');
$tenant->disableModule('blog');
$tenant->hasModule('blog'); // true/false
```

RBAC (Role-Based Access Control)
--------------------------------

[](#rbac-role-based-access-control)

### Roles &amp; Permissions

[](#roles--permissions)

```
// Check permissions
$user->hasPermission('blog.posts.create');
$user->hasAnyPermission(['blog.posts.create', 'blog.posts.update']);
$user->hasAllPermissions(['blog.posts.create', 'blog.posts.update']);

// Manage roles
$user->assignRole($role);
$user->removeRole($role);
$user->syncRoles([$adminRole, $editorRole]);
$user->hasRole('admin');
```

### Middleware

[](#middleware)

```
// In routes
Route::middleware(['tenant', 'module:blog', 'permission:blog.posts.create'])
    ->group(function () {
        // ...
    });
```

API Response Envelope
---------------------

[](#api-response-envelope)

All API responses follow a consistent envelope format:

```
use Sepehr_Mohseni\LaraModuTenant\Http\Responses\ApiResponse;

// Success
ApiResponse::success($data, 'Operation successful');

// Created
ApiResponse::created($data);

// Paginated
ApiResponse::paginated($paginator, PostResource::class);

// Error
ApiResponse::error('Something went wrong', 500);

// Validation error
ApiResponse::validation($errors);
```

Response format:

```
{
    "success": true,
    "message": "Operation successful",
    "data": { ... },
    "meta": { ... }
}
```

### Base Controller

[](#base-controller)

Extend `ApiController` for convenient response helpers:

```
use Sepehr_Mohseni\LaraModuTenant\Http\Controllers\ApiController;

class PostController extends ApiController
{
    public function index()
    {
        return $this->paginated(Post::paginate(), PostResource::class);
    }

    public function store(StorePostRequest $request)
    {
        $post = Post::create($request->validated());
        return $this->created(new PostResource($post));
    }
}
```

Authentication
--------------

[](#authentication)

### Tenant-Scoped Auth

[](#tenant-scoped-auth)

Use the `TenantUserProvider` to scope authentication to the current tenant:

```
// config/auth.php
'providers' => [
    'users' => [
        'driver' => 'tenant', // Use tenant-scoped provider
        'model' => App\Models\User::class,
    ],
],
```

### Tenant-Scoped Sanctum Tokens

[](#tenant-scoped-sanctum-tokens)

Use `HasTenantScopedTokens` instead of `HasApiTokens`:

```
use Sepehr_Mohseni\LaraModuTenant\Auth\HasTenantScopedTokens;

class User extends Authenticatable
{
    use HasTenantScopedTokens;

    // Creates tokens with tenant context
    $token = $user->createToken('api-token');

    // Revoke all tokens for the user's current tenant
    $user->revokeCurrentTenantTokens();
}
```

### AuthManager

[](#authmanager)

The `AuthManager` provides rate-limited, tenant-scoped login:

```
use Sepehr_Mohseni\LaraModuTenant\Auth\AuthManager;

$auth = app(AuthManager::class);

// Login (rate-limited, tenant-scoped)
$result = $auth->attemptLogin([
    'email' => 'john@example.com',
    'password' => 'secret',
]);
// Returns: ['user' => $user, 'token' => 'plain-text-token']

// Logout current device
$auth->logout($request);

// Logout all devices
$auth->logoutAll($request);
```

Artisan Commands
----------------

[](#artisan-commands)

### Module Commands

[](#module-commands)

CommandDescription`module:make {name}`Scaffold a complete module`module:list`List all modules`module:enable {name}`Enable a module`module:disable {name}`Disable a module`module:migrate {name}`Run module migrations`module:migrate-rollback {name}`Rollback module migrations`module:migrate-status {name}`Show migration status`module:seed {name}`Run module seeders### Module Generators (28 commands)

[](#module-generators-28-commands)

All Laravel `make:*` commands have module-aware equivalents:

```
php artisan module:make-model Blog Post
php artisan module:make-controller Blog PostController
php artisan module:make-migration Blog create_posts_table
php artisan module:make-request Blog StorePostRequest
php artisan module:make-resource Blog PostResource
php artisan module:make-factory Blog PostFactory
php artisan module:make-seeder Blog PostSeeder
php artisan module:make-test Blog PostTest
php artisan module:make-policy Blog PostPolicy
php artisan module:make-event Blog PostCreated
php artisan module:make-listener Blog SendPostNotification
php artisan module:make-job Blog ProcessPost
php artisan module:make-mail Blog PostPublished
php artisan module:make-notification Blog PostCreatedNotification
php artisan module:make-observer Blog PostObserver
php artisan module:make-rule Blog ValidSlug
php artisan module:make-cast Blog JsonCast
php artisan module:make-scope Blog ActiveScope
php artisan module:make-middleware Blog CheckPostAccess
php artisan module:make-enum Blog PostStatus
php artisan module:make-interface Blog PostRepositoryInterface
php artisan module:make-trait Blog Sluggable
php artisan module:make-class Blog PostService
php artisan module:make-command Blog SyncPosts
php artisan module:make-channel Blog PostChannel
php artisan module:make-exception Blog PostNotFoundException
php artisan module:make-provider Blog PostServiceProvider
php artisan module:make-job-middleware Blog RateLimitedJob
```

### Tenant Commands

[](#tenant-commands)

CommandDescription`tenant:create {name}`Create a new tenant`tenant:list`List all tenants`tenant:create-user {tenant}`Create a user for a tenant`tenant:create-role {tenant} {name}`Create a role for a tenant`tenant:assign-role {tenant} {email} {role}`Assign a role to a user`tenant:enable-module {tenant} {module}`Enable a module for a tenant`tenant:disable-module {tenant} {module}`Disable a module for a tenant`tenant:list-users {tenant}`List users for a tenant### Other Commands

[](#other-commands)

CommandDescription`laramodutenant:install`Install the packageConfiguration
-------------

[](#configuration)

Publish and customise the config:

```
php artisan vendor:publish --tag=laramodutenant-config
```

Key configuration options:

```
return [
    // Path to modules directory
    'modules_path' => base_path('modules'),

    // Configurable models (swap with your own)
    'tenant_model' => \Sepehr_Mohseni\LaraModuTenant\Models\Tenant::class,
    'user_model' => \App\Models\User::class,
    'role_model' => \Sepehr_Mohseni\LaraModuTenant\Models\Role::class,
    'permission_model' => \Sepehr_Mohseni\LaraModuTenant\Models\Permission::class,

    // Tenant column name on user and module tables
    'tenant_column' => 'tenant_id',

    // Tenant resolution (toggle individual resolvers)
    'resolution' => [
        'header_id' => true,       // X-Tenant-ID
        'header_slug' => true,     // X-Tenant-Slug
        'subdomain' => true,       // Match tenant domain against request host
        'user_relation' => true,   // Fall back to authenticated user's tenant
    ],

    // Middleware aliases
    'middleware_aliases' => [
        'tenant' => \Sepehr_Mohseni\LaraModuTenant\Http\Middleware\IdentifyTenant::class,
        'permission' => \Sepehr_Mohseni\LaraModuTenant\Http\Middleware\CheckPermission::class,
        'module' => \Sepehr_Mohseni\LaraModuTenant\Http\Middleware\EnsureModuleEnabled::class,
    ],

    // API settings
    'api' => [
        'exception_renderer' => true,
        'route_prefix' => 'api/*',
        'pagination' => ['per_page' => 15, 'max_per_page' => 100],
    ],

    // Auth settings
    'auth' => [
        'tenant_user_provider' => true,
        'scoped_tokens' => true,
        'isolate_users' => true,
        'max_login_attempts' => 5,
        'token_expiration' => null,
    ],
];
```

Customisation
-------------

[](#customisation)

### Custom Models

[](#custom-models)

You can swap any model with your own implementation:

```
// config/laramodutenant.php
'tenant_model' => App\Models\Tenant::class,
'role_model' => App\Models\Role::class,
```

Your custom models should implement the relevant contracts:

```
use Sepehr_Mohseni\LaraModuTenant\Contracts\TenantModel;

class Tenant extends Model implements TenantModel
{
    // ...
}
```

### Custom Stubs

[](#custom-stubs)

Publish stubs for customisation:

```
php artisan vendor:publish --tag=laramodutenant-stubs
```

Stubs are published to `resources/stubs/vendor/laramodutenant/` and will be used by the `module:make` command.

Facades
-------

[](#facades)

```
use Sepehr_Mohseni\LaraModuTenant\Facades\ModuleManager;
use Sepehr_Mohseni\LaraModuTenant\Facades\TenantContext;

// Module management
ModuleManager::all();
ModuleManager::enabled();
ModuleManager::find('Blog');
ModuleManager::has('Blog');
ModuleManager::enable('Blog');
ModuleManager::disable('Blog');

// Tenant context
TenantContext::set($tenant);
TenantContext::get();
TenantContext::id();
TenantContext::check();
TenantContext::forget();
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for recent changes.

Contributing
------------

[](#contributing)

Contributions are welcome! Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Acknowledgments
---------------

[](#acknowledgments)

LaraModuTenant is built on the shoulders of giants. Special thanks to these amazing packages and their maintainers for pioneering the patterns and ideas that inspired this work:

- **[nwidart/laravel-modules](https://github.com/nWidart/laravel-modules)** — The original Laravel modular architecture package that set the standard for module management. Much of our module scaffolding and `module.json` manifest approach was inspired by their excellent work.
- **[stancl/tenancy](https://github.com/stancl/tenancy)** — A comprehensive multi-tenancy solution for Laravel. Their approach to tenant resolution, automatic scoping, and tenant-aware events served as a fantastic reference.
- **[spatie/laravel-permission](https://github.com/spatie/laravel-permission)** — The gold standard for roles and permissions in Laravel. Our RBAC system draws heavy inspiration from their clean, trait-based API design.
- **[spatie/laravel-multitenancy](https://github.com/spatie/laravel-multitenancy)** — A beautifully opinionated multi-tenancy package by Spatie. Their single-database tenancy patterns influenced our tenant scoping implementation.
- **[archtechx/tenancy](https://github.com/archtechx/tenancy)** — An innovative approach to Laravel tenancy focusing on developer experience and flexibility.
- **[Laravel](https://github.com/laravel/framework)** — The framework that makes all of this possible. Thank you Taylor Otwell and the entire Laravel community.

We are grateful to the open-source community for sharing their knowledge, code, and creativity. If you find LaraModuTenant useful, please consider giving these packages a star as well. ⭐

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance81

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

102d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ee4894771ae3ecf9a2d11f98128ea6ee1b75f545f2c1f96928592b80c1013b9a?d=identicon)[sepehr-mohseni](/maintainers/sepehr-mohseni)

---

Top Contributors

[![sepehr-mohseni](https://avatars.githubusercontent.com/u/64346646?v=4)](https://github.com/sepehr-mohseni "sepehr-mohseni (4 commits)")

---

Tags

apilaravelpermissionsrbacmodulesmodularsaastenantmulti-tenancy

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/sepehr-mohseni-laramodutenant/health.svg)

```
[![Health](https://phpackages.com/badges/sepehr-mohseni-laramodutenant/health.svg)](https://phpackages.com/packages/sepehr-mohseni-laramodutenant)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76518.2M120](/packages/laravel-mcp)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k51.0M7.6k](/packages/larastan-larastan)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9742.3M121](/packages/roots-acorn)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
