Ideas on multi-tenant Rocket Chat support


#1

Hey guys,

Really love the work you’re doing. We’re working on multi-tenant support for our application (org1.domain.com, org2, org3 etc) and I have a few ideas I’d be keen to run past everyone before we investment development dollars.

I am very new to this to please point out any mistakes I make!

  1. Dynamically connecting to different org’s mongo db by parsing subdomain

Something like: https://stackoverflow.com/questions/22588253/dynamic-database-connection-to-mongodb-or-mongoose-from-nodejs

  1. Use mizzao/partitioner to separate database for different organisations

What is the best way to approach this problem?


#2

Okay guys!

I’ve decided to go with #1 given I don’t want to mess around with #2 for now.

I understand the #1 isn’t 100% fully scalable to 1,000’s of communities. I’ll post any solutions I come up with!

Steve


#3

Hi @steve

Thank you for posting the topic here for further discussion!

As you’re aware, this has been an in-demand, yet thorny and difficult engineering undertaking since the beginning of our project. History of which is more or less documented on this long running issue:

Behind the scene, we have seen no less than 3+ attempts (some heavily funded) using the documented approaches that had resulted in either:

  1. abandonment
  2. perhaps a code fork (public/private) that satisfied the participant’s particular requirements, but not “good enough” for upstream merge because it did not solve the general problem

Our learning during these 3+ years of community attempts and feedback has been:

a) the mizzao partitioner approach is likely not the solution as devoted groups have attempted and abandoned; this is especially relevant as we continue to remove the dependency of our code on the Meteor framework moving forward

b) the general PARTITIONING and SECURED ISOLATION BETWEEN TENANTS problem is extremely difficult to solve at the Javascript App level (it has no prior art!), and yet ultimately a HARD REQUIREMENT for the solution to be generally acceptable (for any specific set of requirements - some intermediate level of secured partitioning might be acceptable)

FWIW - In order to move on with multi-tenant in production (see our cloud offerings if you are interested), we ourselves have leveraged the industry wide movement of adopting orchestrations of lightweight containers to achieve a level of secured isolation between tenants that is acceptable to our own requirements.

Having shared that, we remain continually hopeful (with receptive open mind) of innovative solutions from our community.


#4

@sing.li Thanks for the points!

We successfully enabled multi-tenant for our purposes. The key that allows us to do that is ignoring the secured isolation between tenants rule (as our app is for consumers, there is no need for this)

For others out there, to recreate this:

  1. Parse subdomain
  2. Store it in Sessions variable in Meteor client (to use in other parts of the app), also add it as a customField in both Rooms and Users
  3. Implement a new find() function for Rooms and Users that intercepts a query and adds in the subdomain filter
  4. We needed server side user session tracking (like Sessions but for the server) so we know which subdomain to use for each call. We saved this.connection.id, subdomain and userId down.
  5. Do some cosmetic changes in the front end to filter by subdomain (e.g. stuff like RoomList)

Apart from the isolation point, are there any vulnerabilities that you can see?