LineXa Studio started as a tool for one team. Turning it into a platform where many companies each have their own workspace raised the most important design question we have faced so far: how do you make sure one customer can never see another customer's projects?
Two ways to do multi-tenancy
The common approach is to keep everyone in the same tables and add a "tenant" column to every row. It is simple to start with, but every query has to remember to filter by tenant, forever. One forgotten condition is enough for data to leak across customers.
The other approach is to give each customer their own database. It is more work to run, but the isolation is structural rather than a convention every line of code has to respect.
What we built
LineXa Studio now uses both, each for what it is good at:
- A main database holds what the platform itself needs: workspaces, plans, enabled services, LineXa staff and customer accounts.
- Each workspace has its own database for its projects, environments, deployments, activity and Google Cloud settings.
The workspace a request belongs to always comes from the signed-in user's token, never only from the address in the browser. A user of one workspace has no path to another workspace's database.
Running it without surprises
- Provisioning is automatic. A system job creates the database for a new workspace, with its own credentials, so the API itself does not need the rights to create databases.
- Migrations run everywhere. Schema changes are versioned and applied to the main database and to every workspace database, so they never drift apart.
- Nothing was lost on the way. The data from before workspaces existed was moved into a first workspace as part of the release.
The result is a platform where isolation does not depend on every developer remembering a filter, which is exactly where we want it to come from.