Live data from Hacker News

Ask HN: How come there is no example code for B2B-SaaS apps?

news.ycombinator.com

71–80 of 94 posts

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#71

In my experience, a lot of projects start off with shared tenancy (using a tenant id discriminator in the database) and eventually migrate to completely separate schema for each tenant (i.e. a separate “installation” of a single-tenancy app for each tenant) to avoid security and architectural pitfalls. Once you’ve done that, you don’t have to worry about forgetting a `WHERE tenantId = foo` somewhere and leaking data.…

Thanks for this clear explanation. I’m a non developer currently experimenting with no code apps, I’m using userid filtering to segregate data between users and it feels “wrong” but it’s reassuring to see that it’s a pretty normal starting point before having a more mature architecture

I'm contemplating writing an article about "things that are bad but you should absolutely do anyway when you start" to help with this analysis paralysis.

Interested?

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#73

In my experience, a lot of projects start off with shared tenancy (using a tenant id discriminator in the database) and eventually migrate to completely separate schema for each tenant (i.e. a separate “installation” of a single-tenancy app for each tenant) to avoid security and architectural pitfalls. Once you’ve done that, you don’t have to worry about forgetting a `WHERE tenantId = foo` somewhere and leaking data.…

using an ORM it's very simple. once you setup the relationships between models, you always use the highest level model as the entry point of your query and the ORM will scope the query for you. ie in Rails, if your highest level model is Account you just always use @account.customer.find(18). the Rails ORM will automatically scope the query to the current account. using multiple schemas becomes a nightmare when you w…

> the Rails ORM will automatically scope the query to the current account.

While that is true for simple queries it is not a valid statement for secure multi tenancy.

For example in this scenario: Account (Id). Order (Id, AccountId, CustomerId). Customer (Id, AccountId). You need to ensure Order can only use CustomerId that belongs to Account.

Rails does not include support for restricting deep relationships (grand children) to an account. Basically an attacker can misuse foreign keys from other accounts in new records (add a CustomerId from another Account on Order) or read data in relationship queries when initiating objects (show customer info from another account in an order).

There are ways of mitigating this but it requires doing more complex manual validation methods.

> using multiple schemas becomes a nightmare

There are gems that will solve some of this complexity but it is a risk. The most popular one is somewhat unmaintained.

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#74

One of the largest open-source Rails apps has all of those features: Canvas LMS[1]. It uses Switchman[2] for abstracting the multi-tenancy logic. Their approach has scaled to millions of concurrent users, but admittedly not helpful if you’re looking for a guide since the code is buried in a legacy monolith. Part of the reason there isn’t a generic guide to this is that multi-tenancy is probably a premature optimizati…

Nice. It's amazing so many Rails multi-tenant projects but almost nothing in the Node.js world

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#75
post #60

https://github.com/async-labs/saas "Build your own SaaS business with SaaS boilerplate. Productive stack: React, Material-UI, Next, MobX, WebSockets, Express, Node, Mongoose, MongoDB. Written with TypeScript"

This again, doesn't support multi-tenant (B2B) SaaS. Am I wrong?

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#76
https://github.com/vanilla/vanilla can be run in a “multi-tenant” setup. It is always done with separate databases and configs though.

Localhost setups are always multi-tenant, even if our infrastructure is more strongly isolated. In the end, if you can load different configurations for your app at runtime, and that configuration includes info about how to connect to your DB, cache, etc, then it’s pretty easy to do.

https://github.com/vanilla/vanilla-docker/blob/master/docs/v... this is an example of how we do the localhost setups, although I’d using separate DB credentials for any production site.

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#77
post #62
post #15

Earlier quoted context omitted.

Having built a number of these, it's not that simple. For example do you put a tenant column on every table, have a separate table per tenant, or have a separate schema or database? There are tradeoffs for each approach and lots of gotchas you wouldn't expect. Like if you use a separate table or database, migrations take forever, you can run into file descriptor limits in your database, etc.

This leads to answer, which is: just start building, whatever option you will choose you will run into gotchas. So no point of overthinking it.

That there are tradeoffs with each option does not mean all options are equal at all.

Doing a little research first, and thinking about which tradeoffs matter most in your particular case could save you a lot of effort rewriting things down the road.

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#78
post #34
post #15

Earlier quoted context omitted.

Having built a number of these, it's not that simple. For example do you put a tenant column on every table, have a separate table per tenant, or have a separate schema or database? There are tradeoffs for each approach and lots of gotchas you wouldn't expect. Like if you use a separate table or database, migrations take forever, you can run into file descriptor limits in your database, etc.

Separate table per tenant? Not unless you have/expect 2 to 5 tenants otherwise you run into the issues you describe above. Having a database per tenant has always interested me. It make sense if the databases will be different (contain other tables) Adding a tenant id to the tables that require them makes sense. The best approach is to create a pivot table between users and tenants that holds user_id and tenant_id. U…

The limit is a lot higher than 2 to 5, but I think sooner or later it will get you. Until then you will suffer a slow death by a thousand migrations.

A separate database is best used if you need an absolute firewall between the tenants for security reasons. Almost no bug can ever let one tenant see the data from another. If they share tables, it's easier to make that mistake.

The downside is you can't have quieres across all your tenants, so you'll want a BI database that brings all the data together anyway.

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#79
post #15

Earlier quoted context omitted.

Having built a number of these, it's not that simple. For example do you put a tenant column on every table, have a separate table per tenant, or have a separate schema or database? There are tradeoffs for each approach and lots of gotchas you wouldn't expect. Like if you use a separate table or database, migrations take forever, you can run into file descriptor limits in your database, etc.

That's true, but just looking at the code of some example application you've found online won't shed any light on what those trade-offs are.

Probably not, but there are articles on the subject that are helpful. I've found them before.

Re: Ask HN: How come there is no example code for B2B-SaaS apps?

#80
post #28

In my experience, a lot of projects start off with shared tenancy (using a tenant id discriminator in the database) and eventually migrate to completely separate schema for each tenant (i.e. a separate “installation” of a single-tenancy app for each tenant) to avoid security and architectural pitfalls. Once you’ve done that, you don’t have to worry about forgetting a `WHERE tenantId = foo` somewhere and leaking data.…

Interestingly, I've only seen the opposite, going back to the 90s. Eventually managing N schemas ends up being difficult, and you're also fighting against the database.

Yeah 100%. Multi-tenant as implemented this way with separate infrastructure works ok for very small values on N. Once you’re into N > 100s or 1000s then you’re absolutely not reducing complication.
Post reply on HN