Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Multi Tenant Bundle Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a prerelease (v1.0.0-rc.12) of the multi-tenant bundle. Pin the exact version rather than floating on ^1.0 — a stable tag will renumber things.

  1. Require the exact constraint: composer require zhortein/multi-tenant-bundle:v1.0.0-rc.12. If your root minimum-stability is stable, add an explicit constraint for this package or a prefer-stable allowlist.
  2. Read two things first, in this order: docs/object-storage-audit.md (the public audit contract — this defines the interfaces you'll code against) and docs/migration-rc11-to-rc12.md (adoption and rollback — read the rollback half before you enable anything).
  3. Confirm your optional dependencies. Flysystem/S3 are still optional; you only need the S3 adapter stack if you're actually auditing remote locations.
  4. Audit is off by default. Nothing in RC12 runs unless you opt in. Flip the audit flag in config as your first deliberate act, then verify the facade resolves TenantObjectStorageAuditInterface.

The first real use case is a tenant location inventory report: walk the lazy paginated inventory for one tenant, collect structured per-object observations, and render them. Do this against a non-production bucket before you point it at anything you care about — see the pagination-failure behavior in Gotchas.

Implementation Patterns

Paginated inventory as a generator, not an array. The interface is explicitly lazy and paginated. Consume it in a foreach/cursor loop and flush per page (queue job per page, or stream to a report writer). Do not call ->all() mentally — treat the page size as the unit of memory and the unit of retry.

Keep two read paths during rollout. RC11 objects remain readable, but they will surface as identity_absent. Design your reporting layer to accept three states: identity present, identity_absent (historical, expected), and anomaly-sanitized. Do not collapse identity_absent into an error or a null-provenance row — the package is deliberately refusing to invent provenance, and your downstream schema should mirror that refusal.

Write with explicit content plus identity. New writes should construct a versioned LogicalObjectIdentity and use the explicit content-plus-identity write path rather than the legacy implicit path. Version the identity type in your own domain model too, so a future RC13 identity bump doesn't silently change meaning in your stored metadata.

Use the authenticated claim for correlation only. Thread your application correlation ID through the claim to join audit observations back to your own request/job records. Do not use the claim as an integrity attestation — the release notes are explicit that it does not attest content and does not prevent replay by a storage administrator. If your design needs tamper-evidence, that is a separate control you must build.

Scope history explicitly. Historical scopes are opt-in and named. Wrap historical queries in a separate service or repository method so that production "current state" reads never accidentally inherit a historical scope.

Integration seams. The bundle continues to compose with Messenger/Scheduler and the lifecycle hooks; audit is a sibling capability, not a replacement for lifecycle. Feature-flag audit at the tenant level if your tenancy model allows it — the interface is tenant-scoped, and a per-tenant flag gives you a staged rollout without redeploying.

Testing. The release notes call out that critical object-storage/MinIO tests and consumer recipes reject skips, while the wider suite still contains disclosed placeholder skips and PHPUnit mock notices. Mirror that discipline: fail your CI on skipped audit tests, and treat any mock-notice noise in the audit path as a signal to inspect rather than suppress.

Gotchas and Tips

No migrations, in either direction. No SQL, object, or metadata migration runs automatically, and none is shipped. That's convenient for adoption and dangerous for rollback: if you start writing identity-bearing objects, rolling back to RC11 leaves those objects in place with no automated unwinding. The rollback guide tells you what that means; the code will not protect you from it.

Invalid pagination or tenant scope fails the whole page. Deliberate design choice — no partial pages, no silent truncation. Catch and handle at the page boundary, and make sure your loop is idempotent so a failed page can be retried without duplicating report rows. Contrast with isolable entry anomalies, which are sanitized rather than fatal; know which of the two failure classes you're looking at before you add a retry wrapper.

identity_absent is not an error. It is the correct answer for every RC11-era object. Alerting on it will page you constantly on day one of a backfill-free rollout.

The claim is weaker than it looks. Authenticated claim ≠ content attestation ≠ replay protection against a storage administrator. If a compliance or audit stakeholder reads "audit" and assumes cryptographic provenance, correct them now, not at review time.

Nothing operational is included. No downstream integration, no deployment logic, no repair, and no orphan deletion. If you were hoping this release would clean up dangling objects, it does not, and the notes say so deliberately.

Distribution and provenance. Only GitHub-generated source archives are attached — no additional build asset. Verify against the exact SHAs recorded in the promotion PR rather than trusting the tag name. Note also that release review is author self-review with no independent human approval, and the release notes disclose it themselves. For a prerelease that's tolerable; for the eventual stable tag, treat independent review as a precondition on your side before adoption.

Config quirks to check on first boot: confirm the audit flag's actual key name in your installed version's config reference rather than copying from docs — RC docs and shipped config have drifted in prerelease cycles before, and a silently-defaulted-off flag is the most common "feature doesn't work" report here.

Extension points. LogicalObjectIdentity is versioned by design, so the intended extension point is your own domain layer wrapping it, not subclassing it. For custom observation handling, decorate the audit interface in your container rather than forking the bundle — that keeps rollback to RC11 a pure config and compose change.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log