Isolation is enforced at five layers rather than one: the middleware refuses a page request for an account you're not a member of, the server auth layer refuses the same request at the API, the data proxy stamps and filters org_id on every statement, the browser cache is purged when the viewed account changes, and a CI script fails the build when a new hand-written query forgets its scope.
Also called: data isolation · can another company see my data · tenant separation · privacy between accounts
- 1Middleware compares the subdomain-derived org against the user's memberships and bounces a mismatch back to the apex with the impersonation cookie cleared.
- 2serverAuth.getAuthedUser repeats the check server-side and returns null — which routes turn into a 401 — when the user has memberships but none matching the requested subdomain.
- 3/api/db appends the caller's org_id to every select, update and delete and stamps it onto every insert, ignoring any org_id the client sent.
- 4The browser purges all app localStorage whenever the viewed account changes.
- 5scripts/check-org-scoping.mjs statically flags any new direct query against an org-scoped table that never mentions org_id.
The comment in serverAuth names the incident that produced the whole stack: before the membership check, the function 'returned whatever orgId the URL pointed at without verifying the user was actually a member. A worker on tenant A could type tenantB… and see all of tenant B's data with worker permissions.' It was discovered when a worker legitimately invited to one builder's account navigated to another builder's subdomain and saw an eight-figure pipeline that was not his employer's. The layered design is stated in the same block: API requests get a 403, page requests get a redirect, 'so this manifests as you got redirected rather than a stuck error screen.' The standing rule in this codebase is that isolation is absolute — no sub-account's data, notifications or business details may ever reach another sub-account.
- A signed-in user guessing another company's URL could read that company's data.
- One forgotten filter in one hand-written query is a silent cross-account leak with no database backstop.
- A browser that has viewed two accounts could paint one account's cached data under the other's name.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →