rls policies or a tenant_id filter in the app layer for a 3-person b2b saas Multi-Tenant
Converting a single-tenant app to multi-tenant. 40 tables, 3 developers, a customer who wants it in Q3.
Only our Node server talks to Postgres - no browser client, no mobile app hitting the database directly. Given that, RLS feels like a lot of policies to write and test for a guarantee I could get with a query wrapper that always adds where tenant_id = $1.
Tell me why I am wrong, or that I am not.
@supa_okonkwo · 5mo ago · 3 replies
You are not wrong, and the deciding question is exactly the one you asked: who holds the connection?
If untrusted clients query the database directly, RLS is not optional - it is the only thing standing between a user and every row. If only your server connects, RLS is a second line of defence with a real cost: 40 policies, a test suite for them, and a class of confusing performance surprises.
With three people and a Q3 date I would do the app-layer wrapper properly - one function that every query goes through, tenant id from the request context, and a lint rule banning raw client access - then add RLS table by table afterwards, starting with the three tables where a leak would end the company.
Reply
Report
@layoverlurker · 5mo ago
"Start with the three tables where a leak would end the company" reframed this for me. It is not 40 policies, it is 3 policies now and 37 later or never.
Reply
Report
@edge_runtime_bo · 5mo ago
Just make sure "later" has a ticket with a date on it. Every team I know that said this shipped the three and then discovered two years later that the reporting service was reading a table nobody had gotten around to.
Reply
Report