Jotting down some of my thoughts. Some of these may be a repetition from above.
Overall, I think we trying to fit in way too many use-cases in the first cut.
Mental Model
While designing, having a mental model of each tenant having their own physical DB will help. Asking what would happen if each tenant had their own DB will immediately tell us what the solution should be.
Another idea is to draw an analogy. This feature is very analogous to Process’ Virtual Memory or VMs hosted on an ESX and we can take inspiration from those battle-tested analogies as well.
Yes, other DBs may allow some exotic features (such as user logs in only once for all namespace, user can access >1 namespace, cross namespace txn etc) but they either break the mental model or are complex to implement. As a first cut of this feature, we should aim for simplicity and then iterate.
We can address always add more in a subsequent iteration when we have some feedback and field experience
Assumptions / Notes
- Each user in a DB cannot / should not be able to access other namespaces. This would not have been possible in the case of 1DB / tenant scenario, so we extend to namespace. The corollary to this is that a user can only be part of one namespace.
- In rare situation, if an admin/user needs access to multiple namespaces, they create a user in each namespace of interest.
- The exception to the above is the Dgraph guardian users. These users can access any namespace and will only generally be used for managerial / administrative operations and onboarding tenants/namespaces. No tenant will have a user in this group.
- Now, within a namespace, each tenant can have their own guardian(s) limited to that namespace. Again, tenant users have no visibility of namespaces, to them, it is as if they are operating on their own exclusive DB.
- The default namespace should mostly be used for administrative purposes. Ideally, no tenant’s data should ever go in this namespace. This also means that any query / mutation / alter operation should be attached to a namespace specified by the client in the same namespace via ACL.
- As we discussed, the namespace can be made part of the jwtToken when a user logs in. This will make it transparent to the user / clients. Inserting it into jwtToken ties the namespace to the ACL rules of the user, so a user must be logged in into a namespace and the ACL will check if the user belongs to it.
- For OSS or when ACL is turned off, either everything goes into the default namespace or there is no namespacing at all so it is compatible with older versions. I prefer latter but it may be more complex to implement.