
Key takeaways
- Every organization-owned document carries an organizationId
- The token, a guard and the query layer each enforce the boundary independently
- Controllers never trust an organizationId sent by the client
- Super Admin routes are a separate, explicitly marked set
Why tenant leaks happen
Cross-tenant leaks are rarely dramatic. They come from one query that forgot a filter, or one endpoint that trusted an id from the request body. A single line of defence is one mistake away from a breach.
Layer one and two: the token and the guard
The access token embeds the user id, role and organizationId. A scope guard reads that claim and places it on the request context. From then on, handlers use the context value and ignore anything the client sends.
Layer three: the query
Services follow a base pattern that requires an organization id on every find, update and delete against tenant-scoped collections. Even if a guard were misconfigured, the data layer would still refuse an unscoped query.
Keeping Super Admin separate
Platform administrators need to see across organizations, so their endpoints bypass scoping. They live in a distinct, clearly marked set of routes guarded by the SUPER_ADMIN role only, which keeps the exception visible and reviewable.