mostbyte / multidomain
This is my package multidomain
Requires
- php: ^8.3
- illuminate/contracts: ^11.0||^12.0
- knuckleswtf/scribe: *
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
README
This package provides full-featured multi-tenancy support for Laravel applications. It allows you to create and manage isolated database schemas or connections per tenant, simplifying the development of SaaS and modular systems.
Installation
You can install the package via composer:
composer require mostbyte/multidomain
You can publish and run the migrations with:
php artisan vendor:publish --tag="multidomain-migrations"
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --tag="multidomain-config"
This is the contents of the published config file:
return [
];
Optionally, you can publish the views using
php artisan vendor:publish --tag="multidomain-views"
Usage
use Mostbyte\Multidomain\Facades\Multidomain; Multidomain::setTenant('tenant_1'); // Your tenant-specific logic here
Example Workflow
- Create a new schema for a tenant:
php artisan schema:migrate schema
- Run migrations for that tenant:
php artisan schema:migrate migrate
- All tenant-specific models and queries will automatically be scoped to the active schema.
Creating a schema is idempotent: running mostbyte:schema for a tenant whose
schema already exists reports "Schema already exists, nothing to do." and exits
with code 0, so re-running provisioning is safe.
API authentication
The package routes (POST /{domain}/multidomain/{type}) create, migrate and drop
tenant schemas, so they are protected by a shared secret. Every request must carry
it in the X-API-KEY header:
curl -X POST https://example.com/tenant-1/multidomain/schema \
-H "X-API-KEY: ${MULTIDOMAIN_API_KEY}"
Set the secret in the consuming application's .env:
MULTIDOMAIN_API_KEY=your-shared-secret
The check runs before any database access and behaves as follows:
| Situation | Response |
|---|---|
MULTIDOMAIN_API_KEY empty or unset |
403 – fail closed, the routes stay unusable |
X-API-KEY header missing |
401 |
X-API-KEY does not match |
403 |
X-API-KEY matches |
request proceeds |
An unconfigured key rejects every request on purpose: leaving the schema drop
endpoint open is worse than breaking provisioning. Successful requests keep the
existing response shape (200 with {success, status, message}).
VerifyApiKeyMiddleware::class is listed first in the default
config('multidomain.middleware'), but the routes prepend it regardless of what
that config contains. Overriding the middleware list in a published
config/multidomain.php — for example one copied from an older version of this
package — cannot disable the api key check or move it behind the tenant
resolution logic. It is never applied twice if you also list it yourself.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.