13 KiB
Tenancy Package Reference
This reference is for package-specific details that do not need to live in SKILL.md.
Focused References
Load these smaller references for topic-specific work:
installation.mdfor install, publishing, and setup checksconfiguration.mdforconfig/tenancy.phpsectionsidentification.mdfor middleware and resolversrouting-assets.mdfor tenant routes, route modes, cloned routes, and asset routescontext-api.mdfortenancy(),tenant(),run(), andcentral()behaviorbootstrappers.mdfor tenant-aware Laravel service scopingdatabase-tenancy.mdfor database isolation and tenant database managersmigrations-commands.mdfor tenant Artisan commandsmodels-domains.mdfor tenant/domain models and single-database traitsfilesystem-cache-queue.mdfor storage, cache, sessions, Redis, and queueslifecycle-jobs.mdfor events, provisioning, and cleanup pipelinesresource-syncing.mdfor synced central and tenant resourcesimpersonation.mdfor tenant user impersonationpending-tenants.mdfor pending tenant poolsrls.mdfor PostgreSQL row-level securityfeatures.mdfor optional package featuresintegrations.mdfor URL, mail, broadcasting, Fortify, Scout, Livewire, Telescope, and Vitetesting.mdfor test coverage guidance
Main Entry Points
src/TenancyServiceProvider.phpsrc/Tenancy.phpassets/config.phpassets/routes.phpsrc/helpers.php
Published Files
The package publishes:
config/tenancy.phproutes/tenant.phpapp/Providers/TenancyServiceProvider.phpdatabase/migrations/2019_09_15_000010_create_tenants_table.phpdatabase/migrations/2019_09_15_000020_create_domains_table.php- impersonation migrations
- resource syncing migrations
tenancy:install also creates database/migrations/tenant.
Service Provider Behavior
TenancyServiceProvider:
- merges
assets/config.phpintotenancy - binds
Stancl\Tenancy\Database\DatabaseManageras a singleton - binds
Stancl\Tenancy\Tenancyas a singleton - binds the current tenant to the
Stancl\Tenancy\Contracts\Tenantcontract - binds the current domain to the
Stancl\Tenancy\Contracts\Domaincontract - registers configured bootstrappers as singletons
- binds the configured unique ID generator to
UniqueIdentifierGenerator - registers package commands
- publishes config, routes, provider, and migrations
- loads package asset routes when
tenancy.routesis enabled - boots configured features through
tenancy()->bootstrapFeatures() - registers middleware groups:
clone,universal,tenant,central
Core Runtime API
Stancl\Tenancy\Tenancy exposes:
initialize(Tenant|int|string $tenant): voidrun(Tenant $tenant, Closure $callback): mixedcentral(Closure $callback): mixedend(): voidreinitialize(): voidbootstrapFeatures(): voidgetBootstrappers(): arrayfind(int|string $id, ?string $column = null, bool $withRelations = false)
Use these runtime methods instead of rolling your own context switch logic.
Default Models
From assets/config.php:
tenancy.models.tenant=>Stancl\Tenancy\Database\Models\Tenanttenancy.models.domain=>Stancl\Tenancy\Database\Models\Domaintenancy.models.impersonation_token=>Stancl\Tenancy\Database\Models\ImpersonationToken
The default tenant key relation column is tenant_id.
Tenant ID Generators
Supported generators exposed in config:
UUIDGeneratorULIDGeneratorUUIDv7GeneratorRandomHexGeneratorRandomIntGeneratorRandomStringGenerator
Set tenancy.models.id_generator to null only when the app intentionally uses auto-incrementing tenant IDs.
Identification Middleware
Available middleware:
InitializeTenancyByDomainInitializeTenancyBySubdomainInitializeTenancyByDomainOrSubdomainInitializeTenancyByPathInitializeTenancyByRequestDataInitializeTenancyByOriginHeaderPreventAccessFromUnwantedDomainsCheckTenantForMaintenanceModeScopeSessions
All package identification middleware inherit package failure handling through IdentificationMiddleware::initializeTenancy(). Failed identification throws a package exception unless an onFail callback is registered.
Resolvers
Resolvers configured in tenancy.identification.resolvers:
DomainTenantResolverPathTenantResolverRequestDataTenantResolver
Resolver config includes:
- cache enablement
- cache TTL
- cache store
- path tenant parameter name
- route name prefix
- request header, cookie, and query parameter names
- custom tenant model lookup column
Default Bootstrappers
Enabled by default:
DatabaseTenancyBootstrapperCacheTenancyBootstrapperFilesystemTenancyBootstrapperQueueTenancyBootstrapperDatabaseSessionBootstrapper
Optional bootstrappers:
CacheTagsBootstrapperDatabaseCacheBootstrapperRedisTenancyBootstrapperTenantConfigBootstrapperRootUrlBootstrapperUrlGeneratorBootstrapperMailConfigBootstrapperBroadcastingConfigBootstrapperBroadcastChannelPrefixBootstrapperBootstrappers\Integrations\FortifyRouteBootstrapperBootstrappers\Integrations\ScoutPrefixBootstrapperPostgresRLSBootstrapperPersistentQueueTenancyBootstrapper
Bootstrapper Semantics
DatabaseTenancyBootstrapperswitches the active database connection into tenant context and reverts back to the central connection.CacheTenancyBootstrapperscopes supported cache stores by prefix and can also scope cache-backed sessions.CacheTagsBootstrapperis the older tag-based cache isolation approach and is less complete than prefix-based cache scoping.DatabaseCacheBootstrapperscopes cache by moving database-backed cache stores onto the tenant connection instead of using prefixes.FilesystemTenancyBootstrappersuffixesstorage_path(), rewrites configured local disk roots, can scope file cache and file sessions, and can enable tenant-aware asset URLs.QueueTenancyBootstrapperinjectstenant_idinto queued job payloads and re-initializes tenancy around queue job execution.PersistentQueueTenancyBootstrapperis the queue bootstrapper variant for cases where worker processes should stay tenant-aware across jobs.DatabaseSessionBootstrappermakes the database session driver use the tenant connection.RedisTenancyBootstrappersets Redis connection prefixes for configured direct Redis connections.TenantConfigBootstrappermaps tenant attributes into arbitrary config keys during tenancy.RootUrlBootstrapperoverridesapp.urland the URL generator root URL, primarily for CLI URL generation in tenant context.UrlGeneratorBootstrapperswaps inTenancyUrlGeneratorso route names and tenant parameters are generated correctly for path or query-string identification.MailConfigBootstrappermaps tenant attributes into mail configuration at runtime.BroadcastingConfigBootstrappermaps tenant-specific broadcaster credentials into broadcasting config and swaps in a tenancy-aware broadcast manager.BroadcastChannelPrefixBootstrapperprefixes actual broadcast channel names with the tenant key for supported broadcasters.Bootstrappers\Integrations\FortifyRouteBootstrapperrewrites Fortify redirect targets so tenant auth flows can land on tenant routes.Bootstrappers\Integrations\ScoutPrefixBootstrappersetsscout.prefixto the tenant key.PostgresRLSBootstrapperswaps the tenant connection to the configured PostgreSQL RLS user and session variable model.
Database Isolation Options
The config supports:
- separate tenant databases
- PostgreSQL schema isolation
- optional permission-controlled database managers
- PostgreSQL RLS
Database manager mappings exist for:
sqlitemysqlmariadbpgsqlsqlsrv
tenancy.database.drop_tenant_databases_on_migrate_fresh controls whether migrate:fresh also drops tenant databases through the package override.
Cache, Filesystem, Queue, And Session Scoping
Important config sections:
tenancy.cachetenancy.filesystemtenancy.redistenancy.migration_parameterstenancy.seeder_parameters
Notable filesystem behavior:
- local disks can have tenant-specific root overrides
Storage::disk()->url()can be overridden with tenant-aware public namesstorage_path()can be suffixed per tenant- file cache and file sessions can be scoped
asset()tenancy can be enabled, but may affect packages that assume global assets
Routes
assets/routes.php registers:
/tenancy/assets/{path?}namedstancl.tenancy.asset/{tenant}/tenancy/assets/{path?}namedtenant.stancl.tenancy.assetfor path identification, behind thetenantmiddleware
The package route mode enum is Stancl\Tenancy\Enums\RouteMode, with central as the default route mode in config.
The service provider also registers empty middleware groups named:
cloneuniversaltenantcentral
These route modes and middleware groups are part of the package routing model and should be preferred over ad hoc tenant-versus-central route branching.
Optional Features
Feature classes shipped in src/Features:
CrossDomainRedirectDisallowSqliteAttachTelescopeTagsTenantConfigUserImpersonationViteBundler
Features bootstrap independently from tenant initialization and are intended to be enabled through tenancy.features.
Feature behavior:
CrossDomainRedirectadds aRedirectResponse::domain(string $domain)macro that swaps the redirect host without rebuilding the whole URL.DisallowSqliteAttachblocks SQLiteATTACHusage by registering an authorizer on SQLite PDO connections, using a native authorizer on PHP 8.5+ and a loadable extension fallback on older runtimes.TelescopeTagsadds atenant:{tenantKey}Telescope tag when tenancy is initialized.TenantConfigmaps tenant attributes into config values using event listeners. This feature is deprecated in favor ofTenantConfigBootstrapper.UserImpersonationadds atenancy()->impersonate()macro, stores impersonation tokens in the configured impersonation token model, validates token TTL and tenant match, logs the user in with the configured guard, and exposesisImpersonating()plusstopImpersonating().ViteBundlerconfigures Vite asset path generation to useglobal_asset()so asset URLs stay central rather than tenant-scoped.
Pending Tenants
Pending tenant support is configured under tenancy.pending.
Important behavior:
include_in_queriescontrols whether pending tenants are included in normal tenant queries.countcontrols the maintained size of the pending-tenant pool.- the package ships dedicated commands for creating and clearing pending tenants.
If a task touches pre-provisioned tenant pools, inspect the pending-tenant commands and model scopes before implementing custom provisioning logic.
Commands
Commands registered by TenancyServiceProvider:
tenancy:installtenants:uptenants:runtenants:downtenants:linktenants:seedtenant:tinkertenants:migratetenants:rollbacktenants:listtenants:dumptenants:migrate-freshtenants:pending-cleartenants:pending-createtenants:purge-impersonation-tokenstenants:rls
Prefer these commands over hand-written loops for tenant maintenance tasks.
Command notes:
tenancy:installpublishes config, routes, service provider, and core migrations, then createsdatabase/migrations/tenant.tenants:migrateappliestenancy.migration_parameters, supports concurrent execution, and can continue with--skip-failing.tenants:rollbackrolls back tenant migrations.tenants:migrate-freshrebuilds tenant schema from scratch.tenants:dumpdumps a tenant schema and defaults the dump path fromtenancy.migration_parameters.--schema-path.tenants:seedusestenancy.seeder_parameters.tenants:runruns arbitrary artisan commands against tenant context.tenant:tinkeropens Tinker in a selected tenant context and supports searching by tenant key or domain.tenants:linkmanages tenant storage symlinks used by tenant-aware public disk URLs.tenants:down/tenants:uptoggle tenant maintenance mode.tenants:pending-create/tenants:pending-clearmanage the pending-tenant pool.tenants:purge-impersonation-tokensremoves expired impersonation tokens.tenants:rlscreates the shared RLS user and row-level-security policies for tenant-related tables.
Related Subsystems
The package also includes:
src/Events/*for tenancy lifecycle, tenant, domain, database, storage, and pending-tenant eventssrc/Listeners/*for bootstrapping and reverting contextsrc/Jobs/*for database and storage lifecycle jobssrc/ResourceSyncing/*for central-to-tenant resource syncingsrc/RLS/*for PostgreSQL row-level security supportsrc/Actions/*for route cloning and storage symlink helpers
When a task touches one of these areas, inspect the relevant namespace before inventing a parallel abstraction in app code.