macpaw/postgres-schema-bundle
Symfony bundle for PostgreSQL schema-based multi-tenancy. Switch the active database schema per request or tenant, integrate with Doctrine, and isolate data without managing separate databases. Includes schema-aware connection and listener support.
tenant_id columns and database-per-tenant), this bundle is the shortest path to a working search_path-switching layer on Doctrine/Symfony, and lets us defer or avoid a custom implementation.search_path on a reused connection. That is exactly the cross-tenant leak class we care about. The upside is that the maintainer is actively fixing isolation-correctness bugs, not just features; the read is reference implementation / vendor-internal code made public, now demonstrably patching safety-critical behaviour. That's a decision input: pilot/fork-and-own (with the fix included) vs. adopt as a dependency.Consider it when:
search_path for you.search_path hygiene in long-lived processes, Doctrine metadata caching per schema, transaction/rollback unwinding, and migration tooling.Look elsewhere (or build in-house) when:
search_path is session state; a leaked or stale search_path is a cross-tenant data exposure bug. v2.0.8 closes a concrete rollback-path hole here, but it does not retire the risk — the rollback path was broken in production-shaped code until very recently, so assume other unwind paths (failed jobs, killed workers, nested transactions, savepoint behaviour) are under-tested. Audit before adoption.To executives (one paragraph): macpaw/postgres-schema-bundle is a small open-source Symfony bundle from MacPaw that gives each customer their own Postgres schema instead of mixing all customers in shared tables. Strategically it buys us a credible data-isolation story for enterprise deals and per-customer customization, without the operational cost of a database per customer. The catch is maturity: it has effectively no public adoption (0 stars, 0 dependents) and appears to be MacPaw's internal tooling published openly — so I'd frame this as "adopt the pattern, own the code" rather than adding a dependency we can't support. The latest patch (v2.0.8) fixes a real isolation bug where a rolled-back transaction could leave the previous customer's schema selected on a reused connection — good news that it's fixed and that the maintainer is on it, bad news that a bug of that class shipped at all and that there's no advisory feed to warn us next time. Recommended path: a time-boxed spike against our real tenant model pinned to ≥2.0.8, then a decision to vendor/fork it or build the equivalent in-house. Cost of finding out is low; cost of discovering a search_path isolation bug in production is not.
To engineering (the ask):
search_path is set and reset correctly per request and per job — including failures and exceptions; (2) transaction rollback explicitly covered — assert search_path after ROLLBACK, after nested/savepoint rollback, and after a rolled-back job in a worker, since that was the v2.0.7 hole; (3) Doctrine metadata/query caches don't bleed across tenants; (4) per-tenant migration fan-out is scriptable and idempotent; (5) connection reuse in queues/workers is safe; (6) performance is acceptable for our tenant mix.How can I help you explore Laravel packages today?