Multi Tennant Saas

Hi,

I’m using strapi to for a SaaS product to help gyms manage their members, trainers and content.

I’m having a really hard time figuring out how to provide a multi-tenant solution, given that this core functionality is not implemented on the strapi side yet see this issue

I’m currently thinking of having a content collection called Organization, with a relation to an Admin User (User type, admin role). Then, in the controllers, filtering out all the data that does not pertain to that Org.

There are many issues with this approach, for example the inefficiency of querying the db and then programatically filtering out most of the query result.

Could you please provide some guidance as to the best way to achieve this given the current strapi release?

4 Likes

Is the issue you are referring to within the Admin panel or the REST/GraphQL routes?

I’m not sure I understand your question.

I’m asking for guidance on how best to implement a multi-tenant solution, given the current strapi constraints (i.e., without waiting for this feature to be implemented).

If I understand you’re asking about which controllers I’d be implementing the cross-organization data blocking functionality:
I was thinking about doing it in the REST api controllers by filtering for data that only pertains to the org that the authenticated admin pertains to. But this solution is sub-optimal

Does that make sense?

Where will each of your tenants be contributing content? Via the Strapi Admin panel or are you sending that from other frontend via REST/GraphQL?

the latter.

I’ll say that my concerns here are:

  1. data isolation
  2. permission and role enforcement for superadmin, tenant admin, tenant employee, tenant’s end user
  3. query performance (is like i mentioned before - if I have to do the isolation on a query result, then i’m executing an unoptimized query)
  4. superadmin visibility across tenants (in a single admin panel)
  5. datamodel (how should I desing my content_types s.t. the above concerns are addressed)

In that case it’s much simpler, you just need to implement some policies, forgive the old example, but this is one I constructed a few months back that more or less focuses on a similar request from another user. You are welcome to take a look and pull whatever you can from it:

And to apply the policies is as simple as defining them via the routes:

In this case the policy was designed to be multi-purpose but you could just as easily create multiple policies for very specific purposes, note that policy logic is basically executed as a scoped Koa middleware, it’s executed before the controller as long as the code sits before the await next() anything after the await next() will be executed after the controller (basically the request chain working in reverse to return the information to the user).

A very rough tree of the request chain would be something like:

  • User makes request
  • Request middlewares are called
  • Users-Permissions plugin validates the request (Also sets the ctx.state.user)
  • Koa matches the route via regex
  • Execute any policies
  • Execute the handler (controller => service => query)
  • Begin reverse back up through all the steps (bypassing Users-Permissions since nothing is ran there)

Hopefully that helps, please do let me know if you figure out a useful solution as I would be interested in taking a look at your code, and don’t hesitate to ask for more information if you need. :slight_smile:

7 Likes

@DMehaffy, thanks for your sample, I too am attempting to solve a similar issue, I was able to isolate all data per organization (using your examples), but I am having trouble with having users (API consumers) under each organization.

I’d like it to be possible for the same person (same email/username) to be able to register twice, under each organization (maybe even using a different password). This means there would potentially be 2 records in the Users table with the same email/username, which is currently not possible.

Any ideas on how I could do that? Thanks in advance!

I am trying to create a SaaS where my clients can sell things to their users, but there’s a chance the same user subscribes to 2 of my clients, and considering the rest of the data structure is identical (and not very complicated) it would be great to use a single Strapi project.

1 Like

Currently that is not possible, if something like this starts to become a requirement for you, it’s quite likely you need to consider multiple Strapi projects to handle your use-case.

Hello @DMehaffy. Really thank you for your contributions to the forum and the community. I’m in the same situation as @anzorb. I’m about to start a SaaS project and I would love to use Strapi as my CMS, however I don’t think Multi Tenancy will be implemented anytime soon. Could you recommend or let me know any CMS alternatives that would work for this? Thank you once again!

None that I can think of that really handle multi-tenancy. It’s an extremely difficult type of application to handle in a general use-case (meaning everyone has different expectations of what is needed).

But yeah probably not anytime in 2021

hi Joey_Baruch : i am very new in strapi and i enjoy because of its super simple to create backend. Thanks to the community.i am aslo thinking about create site using multi tenant. is there any simple example that created with tenant concept. please share it
Thanks

Hello there,

I am very new to strapi and starting to love it very much. At this point, I am thinking about doing a multi-tenant setup for an app that will be used by multiple customers. Is it now possible?

Thanks for your time.

HI is it possible to do it via a header value. if the header contains info about organisation. then change get only users for this organisation.

I am looking for exact same framework allow to develop an SAAS model.

Are there any news about this topic? I would like to implement separate organizations with tenant id in each table for separate the tenants data but for the users i do not know how to implement this because the login system it is different.

A great feature to wait for… Thanks a lot!

Hi,

I assume this also handles authentication?
Has any progress been made on this?

Thanks!!

This solution will violate the GDPR issue. Is there not any possible solution for completely different tenant or database connection? Like, based on the front end or based on some initial loading/requests of API from the front end, can Strapi can connect to only one DB or a specific tenant? Inn this way, we wont need to be concern on separating query or permissions. Also, this approach is perfect for those organisations who have their own roles and permissions.

1 Like

Not in the way Strapi v4 is built no, we completely removed the multi-db connection system entirely

I 2nd @Nazmul_Developer idea around multiple database connections. This makes it much easier to maintain multiple tenants while keeping data separate and without needing to unnecessarily spin up and maintain separate servers. Would be an excellent stopgap to a fully managed multi-tenancy solution as well.

Are there technical concerns around this approach or what is the reason for removing this entirely @DMehaffy ?

Thanks