Permissions and RBAC · Build
Who can do what in a product with several kinds of user
When “admin” means something different for each user type, we check access on the server and keep the model in one table, as on a marketplace with five types.
EngagementHourly · remote
Hours9–18 CET · 4 h overlap
StackTypeScript · Node.js · NestJS
Proof3 case studies
The service in 4 parts
01 · Who it’s for
A product where “admin” means something different for each kind of user, or where access follows a relationship such as a meeting, a document or a team.
02 · What we’ve built
- On a US marketplace, five kinds of user share one codebase and each has at least two roles. A permission is resolved from type and role together, so an operator at a vendor and an operator at a fleet carrier get different permissions. The API’s 506 routes are divided between a public set and an admin set.Case study 08 →
- A meeting platform for healthcare and finance, where someone may open a file because they were given access or because they attended a meeting it is attached to, and one document can belong to several meetings. Every person, meeting, file and signature is a node in a graph, and a permission check follows the links between them, however many there are.Case study 15 →
- In a regulated identity check for a German financial institution, operator permissions were set per action rather than per role. When an action was beyond one operator, the case went to a colleague who held that permission, with a note.Case study 10 →
03 · How we work
01 · CHECKED BY THE APIHiding a button in the interface tidies the screen for that role. The permission itself is checked by the API on every request.
02 · ROUTES PER USER TYPEEvery kind of user gets separate routes. To see what a vendor may do, you read the vendor’s routes.
03 · A TABLE FIRSTWe write one table of user type against action before anything else. On the marketplace that table never existed, so each new developer had the model explained out loud.
04 · Stack
TypeScriptNode.jsNestJSExpressPostgreSQLMySQLNeo4jReact
Proof
Where we’ve done this before
Case study 08 · Marketplace506 routesOn a US marketplace, five kinds of user share one codebase and each has at least two roles. A permission is resolved from type and role together, so an operator at a vendor and an operator at a fleet carrier get different permissions. The API’s 506 routes are divided between a public set and an admin set.Read the case study →Case study 15 · Business systemsSoldA meeting platform for healthcare and finance, where someone may open a file because they were given access or because they attended a meeting it is attached to, and one document can belong to several meetings. Every person, meeting, file and signature is a node in a graph, and a permission check follows the links between them, however many there are.Read the case study →Case study 10 · Identity98%In a regulated identity check for a German financial institution, operator permissions were set per action rather than per role. When an action was beyond one operator, the case went to a colleague who held that permission, with a note.Read the case study →
FAQ
Questions about this service
Use roles when access depends on who someone is, and relationships when it depends on what they are connected to, such as a meeting, a document or a version. Most products need both.
Not always. On the meeting platform it paid off, because permission depended on a chain of links that kept growing. In a relational schema that check becomes a recursive join, and it gets slower with every new kind of relationship.
Yes. First we read what the routes and the API allow today and write it down as one table. Changes come after that.
Next step
Describe the problem and we’ll come back with three options.
The first call takes 30 minutes, and you’re under no obligation.