Product Decisions This Supports
- Architecture: row-level scoping vs. database-per-tenant. This package turns a multi-sprint infrastructure bet into a timeboxed spike inside an existing Filament panel. The question shifts from "can we afford to build it" to "does the contract, procurement questionnaire, and compliance posture actually require it" — and you can answer that with a working pilot instead of a whiteboard.
- Whether to ship an enterprise or regulated-industry tier. Dedicated tenant databases are a defensible answer to security review: data segregation, per-tenant backup and restore, per-tenant point-in-time recovery, clean deletion on churn. The package supplies the admin surface for that tier — tenant and domain management, tenant-aware routing, tenant switching — not the tier itself. It de-risks the build half of the pricing and packaging conversation.
- Build vs. buy for panel-level tenancy glue. Tenant-aware panels, per-tenant migrations, resource scoping, subdomain routing, tenant switchers: every Filament-based SaaS rewrites this and none of it differentiates us. MIT license, zero acquisition cost. It converts an engineering line item into an evaluation line item.
- Scheduling our own Filament 5 upgrade. v5.0.0 targets Filament 5 / Livewire 4 / Laravel 12–13 / PHP 8.2+ /
stancl/tenancy 3.9+, and the Filament 3 line continues on a separate v3 branch. If we adopt, the panel upgrade and the tenancy work should land together — two migrations of the same surface is the expensive path.
- Self-serve onboarding roadmap. Provisioned workspace plus a tenant-scoped panel is the substrate for signup → workspace ready → invite teammates with no human in the loop. v5's creation fixes (owner written inside
$tenant->run(), operator-supplied unique ID retained, seeding no longer blocked by the application seeder) shrink the failure surface of that exact flow — which is where onboarding tickets come from.
- Multi-client / agency delivery model. One codebase, one deploy, isolated client databases. Cuts per-client hosting and per-client upgrade overhead for an internal platform team or a consultancy running many client instances.
- Sequencing a migration off a single shared database. If customers are pushing on isolation and we're row-scoped today, this gives an incremental path — pilot one panel, prove provisioning and isolation, then expand — instead of a big-bang rewrite.
- Pricing and packaging inputs. Database-per-tenant carries real marginal cost per customer (provisioning, storage, backup, migration runtime). Piloting here produces unit-economics numbers you can quote an isolation tier against, rather than guessing.
When to Consider This Package
Adopt it when most of these are true:
- The stack matches exactly: Filament 5, Livewire 4, Laravel 12 or 13, PHP 8.2+,
stancl/tenancy 3.9+. Anything else is a branch switch or a rewrite, not a version constraint — verify before the estimate is written, not after.
- Database-per-tenant is already the leading candidate. If isolation is a nice-to-have and row-level scoping with a
tenant_id column satisfies every requirement, this is solving a problem we don't have.
- We are prepared to own the operational perimeter. The package covers panels, resources, tenant/domain records and provisioning. It does not cover per-tenant cache prefixes, session isolation, per-tenant storage roots, deletion cleanup, or Octane/queue-worker teardown. Budget for that work explicitly; it is real and it is ours.
- We can accept vendor risk. 62 stars, zero dependents, a small maintainer base, and a history of breaking changes across major lines (v3 → v5 moved provisioning flow, changed the plugin class name, changed seeding behaviour). The mitigation is architectural: wrap everything behind our own
TenantManager so upgrades become a one-class diff. If the team can't commit to that discipline, discount adoption heavily.
- We are willing to write the isolation tests ourselves. The shipped factory and Pest suite are a starting point; the two tests that matter (tenant connection returns tenant data, central connection still returns central data) are on us.
- Launch is not next week. This is a pilot-and-prove dependency. It needs a vertical-slice spike — create tenant → provision database → run migrations → initialize → hit the tenant panel — before it earns a place on the roadmap.
Look elsewhere when:
- We need a managed, SLA-backed tenancy platform with support, or the customer contract requires a named vendor with a security programme.
- The requirement is data residency, per-tenant encryption keys, or compliance certification — those are infrastructure and process decisions this package doesn't touch.
- The team is on Filament 3 with no upgrade appetite; the
v3 branch exists but pins us to a maintenance line.
- Tenancy is the product differentiator rather than plumbing. Then the abstraction's constraints (operator-supplied IDs,
data JSON instead of a database column, opt-in seeding) become product constraints.
How to Pitch It (Stakeholders)
To executives: This is an MIT-licensed, zero-cost UI layer for multi-tenancy in our existing admin panel. It doesn't decide our architecture — it lets us test database-per-tenant in weeks instead of quarters, so we can price an isolation tier and answer enterprise security questionnaires with evidence. The spend is engineering evaluation time, not a license. The risks are a small upstream project and real operational work around it (backups, storage, cache, teardown), and both are contained by a thin internal abstraction layer we should build on day one.
To engineering: It's a Filament UI and routing layer over stancl/tenancy — not a bespoke implementation. $tenant->run() is the universal primitive for anything tenant-scoped; migrations split into central and tenant directories; queues carry the tenant id in the payload and re-initialize explicitly. Three facts to internalize: the tenant id is whatever the operator typed and is effectively permanent; the database name lives in a data JSON accessor, not a column; and seeding is opt-in and silent when unset. Filament's getTenants() contract resolves against the central connection while panel queries go to the tenant one — that seam is our top auth-bug source. Wrap provisioning, switching and seeding in a single TenantManager, write the two isolation tests first, and treat every upstream major as a diff in one class.
To product and support: Tenant creation, ownership, and workspace readiness are the flows this touches, and they're the ones that generate tickets. The v5 fixes materially reduce "workspace exists but is empty" and "owner exists but can't log in" failures — provided we set the tenant seeder class deliberately and validate the unique ID at creation. Make the ID read-only after provisioning; renaming it later means renaming a database.