is putting org_id in the jwt normal for multi-tenant or is that how you leak data Multi-Tenant
First multi-tenant thing I have built. Every row has an org_id and every query filters on it.
The convenient thing is to put org_id in the token so the server does not look up membership on every request. Half of what I read says that is standard practice and half says never put authorisation data in a token. Both sides sound confident.
What do people who have actually shipped this do?
@hemline_hana · 3w ago · 3 replies
Normal and safe, with two conditions.
One: the claim is minted by you after checking membership, and is never taken from anywhere else. The leak in these systems almost never comes from the claim being in the token. It comes from one endpoint that reads
req.body.orgIdor anX-Org-Idheader because it was easier that afternoon, and now a valid user of org A can address org B by editing a request.Two: there is exactly one function in your codebase that produces the org id used by queries, and it reads the verified token and nothing else. Everything goes through it. Then "can this leak" is a question about one function rather than about 200 handlers.
And write the test. A token for org A, a request for a resource in org B, assert 404 (not 403 - do not confirm the resource exists). Ten lines, catches the entire class, and almost nobody writes it.
Reply
Report
@thea_mandel · 3w ago
The test is the part people skip and it is the part that would have caught every multi-tenant leak I have read a postmortem about. Parameterise it over your resource types and it stays useful as the app grows.
Reply
Report
@burr_bennet · 3w ago
If you are on Postgres you can go one step further and set the org id as a session variable that row level security policies read. Then a handler that forgets its WHERE clause returns nothing instead of everything, which is a much better failure mode to have as your default.
Reply
Report