Skip to content
Eitan FeldmanBA, ARGResumeenes
Notes

We took out the auth plugin and wrote our own RBAC

Better Auth's organizations plugin models a flat company. A restaurant group is a hierarchy, and permissions have to inherit down it while never escalating up. Bending the plugin would have cost more than replacing it.

The plugin was not wrong. It models what most products need: a company, its members, and roles inside it. Flat.

A restaurant group is not flat. There is a group, its venues, the floors inside a venue, and the stations inside a kitchen. A manager at venue level should inherit everything below them and nothing beside them. That is not a role list; it is a tree with a non-escalation rule.

The alternative we turned down

Keeping the plugin and modelling the hierarchy alongside it — a second table mapping members to scopes, consulted after the plugin answered. It would have worked, and it would have meant two sources of truth for one question. Every permission check would have had to ask both and reconcile them, and the first time they disagreed we would have had a security bug rather than a rendering bug.

What we did instead

Organizations, membership and scopes in our own schema, with inheritance resolved per permission rather than per role. Not "manager can do X" but "this permission inherits downward from the scope it was granted at".

The cost was real: it is more code and we own it now. The thing that made it the right call is that permissions are the one part of this system where being approximately right is the same as being wrong.