Multi-tenancy is not created by adding a tenant identifier to a few database tables. It is an architectural responsibility that crosses authentication, authorisation, data access, storage, background processing, caching, configuration, logs, and support tools.
The safest starting point is to treat tenant context as required information that enters with the request and remains explicit through every layer. Any operation that cannot identify its tenant should fail closed rather than fall back to a platform-wide query.
Isolation is a system property
- Resolve tenant context from authenticated identity and authorised membership, not from an untrusted request value alone.
- Apply data isolation in a shared query layer or database policy so it does not depend on every developer remembering a filter.
- Carry tenant context through queues, scheduled jobs, file paths, cache keys, and event messages.
- Test cross-tenant access as a security condition across reads, writes, exports, search, and administrative actions.
- Measure latency, failures, queue depth, and usage by tenant while protecting sensitive information.
Configuration without forks
Different organisations will need different modules, approval paths, terminology, and limits. Those variations should be represented through validated configuration, permissions, and feature policies. Repeated tenant-specific code branches make testing harder and allow the shared product to fragment over time.
“A shared platform stays maintainable when variation is governed as data and isolation is enforced as policy.”
— Renovative Lab principle
Reference points
- AWS Well-Architected SaaS Lens — tenant isolation: https://docs.aws.amazon.com/wellarchitected/latest/saas-lens/tenant-isolation.html
- PostgreSQL documentation — row security policies: https://www.postgresql.org/docs/current/ddl-rowsecurity.html
