zhortein/multi-tenant-bundle
A multi-tenant bundle for PHP applications that helps isolate tenants, resolve them per request, and manage tenant-aware configuration and database connections. Useful for building SaaS platforms with clean tenant separation and less boilerplate.
What v1.0.0-rc.12 delivers. The release extends the existing facade with an optional TenantObjectStorageAuditInterface providing lazy, paginated tenant location inventory, explicit historical scopes, and structured per-object observations. It also adds a versioned LogicalObjectIdentity and explicit content-plus-identity writes. Audit remains disabled by default, so the default blast radius for an existing integration is near-zero.
Architecture fit. The package is a multi-tenancy bundle whose validation matrix targets PHP/Symfony versions plus PostgreSQL 16/18, Flysystem/S3, Messenger and Scheduler. That is a Symfony-shaped surface, not a native Laravel one. The "facade" language is ambiguous — confirm whether a Laravel service provider, container bindings, config publishing and tenant-resolution hooks actually exist, or whether a Laravel app would be consuming Symfony-flavoured contracts through adapters. This is the single largest architecture-fit unknown and should be resolved before any design work.
Integration feasibility. Favourable, if the above checks out: the audit surface is additive, opt-in, and reads through the storage abstraction the app likely already has. There are no automatic SQL, object, or metadata migrations, which removes the usual upgrade hazard. The main integration work is on the consumer side — deciding who reads the paginated inventory, how identity_absent is surfaced in reports, and what "historical scope" means for your bucket layout.
Technical risk.
Key questions to put to the maintainer.
Stack fit. Best fit is a Laravel application that already isolates tenant data and writes tenant-scoped objects to an S3-compatible store via Flysystem. If the app uses a single shared bucket with tenant path prefixes, the "tenant location inventory" concept maps cleanly; if it uses per-tenant buckets or per-tenant credentials, confirm the audit can traverse them with the credential model you have. Applications without object storage gains nothing from RC12 and should not take the dependency for this feature alone.
Migration path. Two tiers:
identity_absent by design. Do not plan a backfill of identity for pre-existing objects — the package explicitly refuses to invent provenance, and fabricating it in your own layer would defeat the purpose.Compatibility checks before merging. Confirm PHP version against your runtime, confirm PostgreSQL 16/18 (or your actual engine) is in the supported set, confirm Flysystem/S3 adapter versions align, and confirm Messenger/Scheduler usage doesn't collide with your Laravel queue and scheduler setup — Symfony Messenger semantics do not map one-to-one onto Laravel queues, and that is where surprises usually appear.
Sequencing.
TenantObjectStorageAuditInterface behind a disabled flag.Rollback. Cheap at the feature level (flag off, no migrations to unwind) but not automatically cheap at the data level, since identity write shape is the open question. Nail that down before enabling in production.
Maintenance. Budget for prerelease churn. Expect interface adjustments between RC and GA, and read every RC12→RC13+ release note rather than assuming semver stability. The project presents as small-team or single-maintainer with self-review; plan for the possibility that you become the de facto maintainer of your fork. Decide now whether you have the PHP depth to patch the audit layer in-house.
Support. The release is explicit that no downstream application integration, deployment, repair, or orphan deletion is included. The audit observes; it does not remediate. If a stakeholder reads "audit" and hears "compliance remediation workflow," correct that immediately. Your team owns runbooks for what to do when identity_absent spikes or when a page fails on tenant scope.
Scaling. Lazy pagination is the right shape, but cost and latency scale with object count, not tenant count. A large shared bucket means many ListObjects round trips per tenant inventory, with real per-request billing and throttling exposure on AWS S3. Historical scopes amplify this. Model the page count and list-call volume for your largest tenant before enabling broadly, and cache or snapshot inventory results rather than recomputing per dashboard load.
Failure modes to instrument.
identity_absent rate per tenant — the primary signal that new writes are bypassing the identity path.Ramp-up. Low for a mid-level Laravel developer: the integration is facade calls plus a flag. Call it one to two days to a working spike and one to two weeks to a production-grade consumer with instrumentation, cost modelling, and rollback validation. Add separate time for a security/compliance conversation about what the audit does and does not prove — that conversation, not the code, is the long pole.
Recommendation. Adopt for evaluation behind a disabled flag; do not route compliance or assurance-critical reporting through this capability until GA, independent review, and a Laravel-native integration path are confirmed. Pin by SHA, vendor the archive, and keep a fork-ready posture.
How can I help you explore Laravel packages today?