agentsclimarketplace

Rbac design

Skill JoaoEquer/Oficina/skills/rbac-design

A lean agent harness for AI-assisted development — NestJS + TypeScript + Prisma + PostgreSQL. Skills, rules and commands extracted from real projects.

Install
npx -y skills add JoaoEquer/Oficina --skill rbac-design

Assembled 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:

  1. Map the domains of the system (the "areas": tasks, documents, users, reports, settings...). Medium systems have 8–15 domains.
  2. 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.
  3. Build the role × domain matrix in a readable document (table: rows = roles, columns = domains, cells = allowed actions).
  4. 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.
  5. 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 (workspaceId on Role). 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.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.