Rbac design
A lean agent harness for AI-assisted development — NestJS + TypeScript + Prisma + PostgreSQL. Skills, rules and commands extracted from real projects.
npx -y skills add JoaoEquer/Oficina --skill rbac-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Role-based access control design with roles + granular permissions — role × domain matrix, N:N database modeling and an approval process before implementation. Use whenever the project involves permissions, user roles, access control, admin panels or "who can do what" questions in the system.
SKILL.md
3.2 KB, as published. Nobody here has run it
RBAC design
Badly designed RBAC is guaranteed rework. This is the process and the model that work.
The model: roles + granular permissions (not pure roles)
Pure roles ("admin can do everything, editor can edit") break at the first real exception. The house model:
- Permission = atomic action on a domain (e.g.
task:create,document:approve,report:export). - Role = named set of permissions (N:N role ↔ permission).
- User receives roles (N:N user ↔ role), and the system resolves the effective permission set.
model Role {
id String @id @default(uuid())
workspaceId String
name String
permissions RolePermission[]
}
model Permission {
id String @id @default(uuid())
domain String // e.g. "task", "document", "report"
action String // e.g. "create", "read", "update", "approve", "delete"
roles RolePermission[]
@@unique([domain, action])
}
model RolePermission {
roleId String
permissionId String
role Role @relation(fields: [roleId], references: [id])
permission Permission @relation(fields: [permissionId], references: [id])
@@id([roleId, permissionId])
}
Server-side check via guard/decorator (@RequirePermission('document:approve')). The frontend uses permissions only to hide buttons — never as real control.
The process: matrix before code
Do not implement RBAC straight into code. The correct flow:
- Map the domains of the system (the "areas": tasks, documents, users, reports, settings...). Medium systems have 8–15 domains.
- Map the real roles of the client's operation (not the ones you imagine). Usually 5–8 roles are enough; more than that smells like roles that should be standalone permissions.
- Build the role × domain matrix in a readable document (table: rows = roles, columns = domains, cells = allowed actions).
- Submit it for approval by the architect/tech lead and, when it makes sense, the client. The matrix is cheap to change; code and migrations are not.
- Only after approval, implement — and if implementing into an existing system, verify the real codebase first (do not implement against an imagined codebase).
Known traps
- Implicit permission: an undocumented "everyone can read" becomes a security hole when requirements change. Every permission is explicit in the matrix.
- The ever-growing God role: the "admin" role that accumulates everything. Acceptable, but record that it is a super-user by design.
- RBAC without tenant: in a multi-tenant system, roles and assignments belong to the workspace (
workspaceIdonRole). Global roles only with a recorded decision. - Premature granularity: start with standard actions (create/read/update/delete + the 2–3 domain-specific business actions, like "approve"). Do not invent 40 actions per domain on day 1.