-
-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi tenant, an elegant and easy way #14
Comments
I will definitely be moving a lot of my stuff over from go-pg to bun, I'll probably make another repo with the implementation that I use as a boilerplate. |
Such an approach only works for a single struct, not a slice. Why should we support the first and ignore the latter? Overall it is not clear why make tenant filter so special. I write filters like this and tenant filter is just one of many. |
What we're asking you since |
I mean to be fair, multi tenant implementations are so unique from application to application it's very hard for the ORM itself to properly implement such a system that adequately serves each use case; each use case being good and valid. It is often better to implement multi-tenant safety at the database level with something like row level security. Or by building a layer on top of the ORM you are using and making that layer a common interface throughout your code. |
@elliotcourant any idea on how to use row level security with |
Any orm that is pooling connections is not a good mix for row level security in my opinion. The safest way I've seen it done is to authenticate postgres using a user that only has access to that user's rows. That can be an expensive operation for applications that need to create many sessions to serve data. It might be possible to set a variable's value at the beginning of each session and then enforcing the row level security based on that variable, but then you risk the same problem; if you forget to set the variable in one spot -> now someone is reading someone else's data. But you have significantly overcomplicated your code in the process. Row level security is best implemented where a connection is for a single tenant and thus there is no risk of it being misused. The connection is established for that tenant's sole user within postgres, and closed at the end of the work so that it is not re-used by a different tenant. @vmihailenco do you want to move this do discussions? |
Long time ago I asked this go-gorm/gorm#3832. |
To handle multi-tenancy using postgres RLS pgEnv := map[string]string{"tenant_id":"tenant_1" , "user_role": "admin"}
ctx := context.WithValue(context.Background(), "pgenv", pgEnv)
err := db.NewSelect().Model(book).Column("title", "text").Where("id = ?", 1).Scan(ctx) We can check if the context have a value named "pgenv", if present then iterate over it and run the
|
@adpande I love you! ❤️ @vmihailenco, @elliotcourant what do you think about? |
It is possible to add type BeforeSelectQueryHook interface {
BeforeSelectQuery(ctx context.Context, query *SelectQuery) error
}
type AfterSelectQueryHook interface {
AfterSelectQuery(ctx context.Context, query *SelectQuery) error
} I personally think that such design brings more problems than it solves but I can live with it.
👍 I am even more skeptical and believe that it is better to write a little bit more code and repeat yourself here and there rather than relying on hooks & hacks.
You are lucky if this is the only / top10 problem in your app. It is easy to spot and even easier to fix... |
Hooks are re-worked in v0.2.0 - https://bun.uptrace.dev/guide/hooks.html#model-query-hooks. This example demonstrates how to modify query based on values in context. |
Closing since I don't know what else can be done here. Also see this disclaimer regarding hooks. |
Now that you have refactored a lot of things in
go-pg
andBun
is born, I think it's the right time to ask you something that I have long wanted to solve easily withgo-pg
.I'm talking about the filter with tenant_id for tenantable models.
Example:
If
Player
is tenantable (hasTenant
field):I would like to add on each query a
where
filter like:123
here comes from user'stenant_id
column.I saw that there are a lot of hooks available but not the one before a Select which is what we need here.
Can you suggest an elegant way?
Since you also worked on a solution here: https://github.com/elliotcourant/go-pg-multitenant, I would like to hear your opinion on Bun too, @elliotcourant.
The text was updated successfully, but these errors were encountered: