There are valid reasons why a Mendix developer would want to deploy a multi-tenant application but I won’t delve into the merits of this requirement on this thread. What I am hoping to is continue to promote an open discussion with Mendix product managers and the wider Mendix developer community on the challenges we struggle with in order to build, deploy and operate multi-tenant applications.
This is not the first thread on this topic but some of the most popular threads listed below go back a few years:
From what i’ve been able to gather through discovery or conversations with other Mendix developers is that most active multi-tenant implementations rely on a Multi tenant administration framework available from the Mendix Marketplace. This module for some reason was demoted from Platform support to Community support a few years ago so if you venture to try this route, you’re on your own as we’ve learned from our own experience diving in.
I’d be curious to learn exactly how many derivative implementations of this module are actively maintained so perhaps we can use this thread to track known implementations.
For those of us who rely on this framework, our TenantAdministration module probably looks something like this.
As we started down this path, it was not so much a problem but as our application and reusable module portfolio grows, it is becoming increasingly difficult to maintain.
I wanted to start a list of pain points that our team is experiencing but hope that others from the community can chime in with their own. The idea is to use this as way to sway Mendix Product Managers to add out-of-the-box support for multi-tenancy.
I know that Mendix 10 introduces Adaptive Solutions but I don’t think this architecture meets the basic requirement of multi-tenancy in the context of a single/clustered Cloud Node setup with a single backing store (database). From reading through the documentation, it seems like this architecture implies increased infrastructure costs from a cloud resource perspective.
Please feel free to add your experiences and/or perspective.
add description to access rules in xpath of an entity
I’ll try to chime in with two of my pet-peeves Security and Performance
All these additional associations and xPath constraints leading back to the Tenant/TenantUser objects are causing additional load on the database. Specially with growing usage (more data, more users) these constraints start to add up and create a serious performance challenge.
Scaling / resource management
Some tenants are bigger than others, paying more than others, but there is no way to; monitor and control the resource usage per tenant. They all get the same access to the app and database resources. Scaling resources (e.g. shards) for more demanding tenants is not possible in the current setup.
Security (user management)
User management is set on a project level (e.g. UserRole A is allowed to manage UserRole B and C) this is handled —as is my current understanding— by xPaths, but if TenantAdministration.TenantUser is a specialisation from System.User the security applied to the TenantUser doesn’t further restrict the access to TenantUser objects. Everywhere in the Mendix application the entity access constraints applied to the specialisation are followed, the entity access constraints on the generalization are overruled (or ignored) by the platform and the specialization rules are applied (Read more: Applying security to inheritance). Except when it comes to the System entity such as System.User (and its specialisations) the XPaths applied to the TenantUser are not further restricting the access to (Tenant)User objects. Not only is this confusing as it contradicts with the rest of the Mendix behaviour, it is also really hard to work with in a Multi-Tenant context.
Security (marketplace modules)
Marketplace modules are usually not built for multi-tenant applications and when their features are exposed to tenant-users additional development work is required to get a secure implementation (data isolated per tenant) for that module. Either by modifying the module itself (implicating maintenance) or by creating specialisations/inheritance for the marketplace module entities (more development work and less performance)
The security of the app already is determined by how well the developer(s) build their app and set the security constraints. But with multi-tenancy setting entity access (and data retrieves) correctly becomes a totally different game, mistakes are hard to find (some marketplace modules/scripts might help) but configuring entity access correctly and in all places is really a burden on the developer.
SaaS / multi-tenant patterns
This problem isn't unique to Mendix and there are different patterns available and documented by others as well. In summary there are options such as:
Standalone single-tenant app with single-tenant database
Multi-tenant app with database-per-tenant
Multi-tenant app with multi-tenant database
Multi-tenant app with sharded multi-tenant databases
Hybrid sharded multi-tenant database model
Neither one of these partterns is particularly well supported by Mendix, but it could offer major improvements to running multi-tenant apps.
Previous Idea-topics on Multi-Tenancy:
It's an idea/limitation that has been raised previously as well both in questions and idea topics, here are some of the previous idea topics:
Which indicates it was and still is a missed opportunity and gap in the Mendix platform
Since we are an ISV with over 10 years of multi tenantcy and multi language experience in Mendix I agree it would indeed be nice if I could just select an entity as my tenant object and the system would just always attach the tenant object to each and every XPath query. Now you get a tenant object like this :)
We do not use that module though. Our application was already build before that and it can be done without this module. But a good example is always nice for developers who do multitenancy for the first time.
And for marketplace modules never adjust the module but always use inheritance when you need objects from that marketplace module and create your own page with the inherited objects. But mistakes can be made. Make sure that you use the devtools from the marketplace to double check your model for the security. Because you will make mistakes even after years of working with inheritance.