Cómo añadir control de acceso basado en roles (RBAC) a tu app
Para añadir control de acceso basado en roles, asigna a cada usuario uno o más roles (por ejemplo, administrador, editor, visor), define qué acciones puede realizar cada rol y comprueba esos permisos en el servidor en cada petición, no solo ocultando botones. Además, comprueba que el registro al que se accede pertenece a la cuenta o al equipo del usuario. Empieza con unos pocos roles fijos en tu base de datos y prueba intentando acceder directamente a los datos de otro usuario.
Autenticación frente a autorización
Dos palabras que se confunden a menudo:
- Autenticación es ¿quién eres?: iniciar sesión. Consulta cómo añadir inicio de sesión a tu app.
- Autorización es ¿qué puedes hacer?: a qué páginas, registros y acciones puede acceder un usuario que ha iniciado sesión.
El RBAC es la forma más habitual de hacer autorización. Es importante: a fecha de septiembre de 2026, el control de acceso roto ocupa el primer puesto del OWASP Top 10:2025, la lista ampliamente usada de los riesgos de seguridad más graves en aplicaciones web. Los fallos típicos son usuarios que leen los registros de otros cambiando un ID en la URL, o usuarios normales que llaman a rutas de API solo para administradores.
Elige un modelo
| Modelo | Cómo funciona | Ideal para | Compromiso |
|---|---|---|---|
| Una sola columna de rol | users.role = admin / member | Apps pequeñas con dos o tres roles | Se complica cuando la gente necesita roles distintos en lugares distintos |
| Roles + permisos | Los roles se asocian a permisos con nombre (invoices.approve); el código comprueba los permisos | Apps cuyas reglas van a crecer | Más tablas; una lista de permisos que mantener |
| Roles por equipo (multiinquilino) | Una tabla de pertenencias: usuario + organización + rol | SaaS donde las personas pertenecen a equipos o espacios de trabajo | Cada consulta debe limitarse a la organización |
| Basado en atributos o en relaciones | Reglas sobre atributos del registro («el autor puede editar su propia entrada») o sobre relaciones (compartido con) | Documentos, compartición, flujos complejos | Más difícil de razonar; valora una biblioteca o un servicio específico |
| Roles del proveedor de autenticación | Tu proveedor de inicio de sesión guarda los roles o las pertenencias a organizaciones | Apps que ya usan un proveedor de autenticación alojado | Atado a ese proveedor; aun así, aplica las reglas en tu servidor |
En la práctica, la mayoría de apps combinan dos cosas: roles para decidir qué tipo de acciones puede hacer alguien, y propiedad para decidir sobre qué registros puede hacerlas. «Los editores pueden editar entradas» es una regla de rol; «…las entradas de su propio espacio de trabajo» es una regla de propiedad. Necesitas las dos.
Empieza más sencillo de lo que crees. Administrador, miembro y visor cubren un número sorprendente de apps. Es más fácil dividir un rol más adelante que desenredar diez roles que nadie entiende.
Diseña los roles antes de escribir código
Escribe primero una tabla de permisos en lenguaje sencillo. Sirve como especificación para la IA y como plan de pruebas:
| Acción | Propietario | Administrador | Miembro | Visor |
|---|---|---|---|---|
| Ver los proyectos del equipo | ✓ | ✓ | ✓ | ✓ |
| Crear y editar proyectos | ✓ | ✓ | ✓ | |
| Eliminar proyectos | ✓ | ✓ | ||
| Invitar y eliminar personas | ✓ | ✓ | ||
| Cambiar roles | ✓ | |||
| Facturación | ✓ |
Decide también los casos límite: ¿puede salir el último propietario? ¿Puede un administrador eliminar al propietario? ¿Qué ve un usuario eliminado?
Paso a paso
1. Ten antes el inicio de sesión funcionando
El RBAC se apoya en la autenticación. El servidor debe saber con certeza quién hace cada petición, a partir de una sesión o de un token verificado, nunca a partir de un ID de usuario que envíe el navegador en el cuerpo de la petición.
2. Guarda los roles en la base de datos
Para una app de un solo equipo, una columna role en los usuarios basta. Para equipos, usa una tabla de pertenencias:
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
Nunca permitas que los usuarios cambien su propio rol mediante una actualización normal del perfil. Los cambios de rol deben pasar por un endpoint específico que compruebe los permisos.
3. Comprueba los permisos en el servidor, en un único lugar
Escribe una función auxiliar, algo como can(user, 'projects.delete', project), y llámala en cada ruta de API, acción de servidor y tarea en segundo plano que lea o cambie datos. Una función central es más fácil de revisar y de probar que las comprobaciones dispersas por el código. Deniega por defecto: si ninguna regla permite una acción, se rechaza.
4. Limita cada consulta
Toda consulta de datos de equipo debe incluir el equipo: where organization_id = :currentOrg, no solo where id = :id. Esto evita que alguien cambie /projects/123 por /projects/124 y vea el proyecto de otra empresa. Devuelve «no encontrado» en lugar de «prohibido» para los registros de otros equipos, para no revelar que existen.
5. Añade protección a nivel de base de datos donde importa
La seguridad a nivel de fila (RLS) de Postgres permite que la base de datos imponga qué filas puede ver cada usuario. Es esencial si el navegador habla directamente con la base de datos (como en algunos backends alojados), y una capa adicional útil para las tablas sensibles en el resto de casos.
6. Refleja los roles en la interfaz
Ahora oculta o desactiva lo que los usuarios no pueden hacer, para que la app no resulte confusa. Esto es solo por usabilidad; las comprobaciones del servidor son las que protegen.
7. Registra las acciones sensibles
Anota quién cambió roles, eliminó datos o exportó registros, y cuándo. Un registro de auditoría ayuda con las consultas de soporte y con los incidentes.
8. Prueba como lo haría un atacante
Inicia sesión con cada rol y prueba cada acción de la tabla de permisos. Después prueba lo que no debería funcionar: llamar a rutas de API de administrador siendo visor, cambiar IDs en las URLs y en las peticiones, o quitarte a ti mismo siendo el último propietario. Merece la pena escribir pruebas automatizadas para la tabla de permisos cuando las reglas se estabilicen.
Prompts que funcionan
Añade control de acceso basado en roles. Roles por organización: propietario, administrador, miembro, visor, guardados en una tabla de pertenencias. Los permisos están en esta tabla: [pega tu tabla]. Crea una única función de servidor can(user, action, resource), con denegación por defecto, y úsala en cada ruta de API. Limita cada consulta por organization_id. Oculta en la interfaz las acciones que el usuario no puede realizar, pero nunca confíes solo en eso para la seguridad.
Revisa cada ruta de API y cada función de servidor de esta app. Para cada una, indica qué datos lee o cambia, si comprueba que el usuario ha iniciado sesión, si comprueba su rol y si limita la consulta a su organización. Corrige las que no tengan alguna comprobación y muéstrame la lista.
Añade una página /admin solo para administradores donde el propietario pueda cambiar los roles de los miembros. Impide eliminar o degradar al último propietario, registra cada cambio de rol con quién lo hizo y cuándo, y asegúrate de que el endpoint de cambio de rol rechace a cualquiera que no sea propietario.
Errores habituales
- Comprobar los roles solo en el frontend. La API sigue abierta para quien la llame.
- Confiar en los IDs que llegan del cliente: un
userIdo unroleen el cuerpo de la petición en lugar de en la sesión. - Consultas sin limitar que buscan por el ID del registro solamente.
- Roles comprobados en las páginas pero no en las rutas de API, las exportaciones, las descargas de archivos o los webhooks.
- Administrador por correo electrónico fijado en el código (
if email === 'yo@...'), fácil de olvidar y difícil de cambiar. - Demasiados roles demasiado pronto, que nadie sabrá explicar seis meses después.
- Sesiones obsoletas: un usuario degradado conserva los derechos de administrador hasta que cierra sesión. Comprueba los roles en la base de datos, o actualízalos, en las acciones sensibles.
Lista de comprobación de RBAC
- Tabla de permisos escrita en lenguaje sencillo, con los casos límite decididos
- El servidor conoce al usuario por la sesión, nunca por los datos de la petición
- Roles guardados en la base de datos; los usuarios no pueden cambiar los suyos
- Una única comprobación de permisos central, con denegación por defecto, usada en cada ruta
- Cada consulta limitada a la organización o a la propiedad del usuario
- Seguridad a nivel de fila donde el navegador pueda llegar a la base de datos
- La interfaz oculta lo que el usuario no puede hacer (solo por usabilidad)
- Acciones sensibles registradas
- Cada rol probado, incluidas las llamadas directas a la API y los IDs cambiados
El control de acceso es un punto de una lista más larga; la lista de comprobación de seguridad para apps creadas con IA cubre el resto. Si estás creando una herramienta para tu propio personal, cómo crear una herramienta interna muestra dónde encajan los roles.
RBAC en Mythex
Mythex no ofrece un sistema de inicio de sesión ni de roles integrado para los usuarios de tu app. Eliges una biblioteca o un proveedor de autenticación y describes los roles, y el agente los conecta con tu código y con la base de datos Postgres de tu proyecto (añadir inicio de sesión a tu app). Los roles de espacio de trabajo de Mythex, como Propietario y Miembro, controlan quién puede editar tus proyectos de Mythex, no quién puede usar la app que publicas. Usa el modo Plan para acordar la tabla de permisos antes de construir, y luego usa el prompt de revisión de arriba y prueba cada rol en la vista previa antes de publicar. Los prompts de seguridad de la documentación son un buen siguiente paso.
Preguntas
¿Qué es el control de acceso basado en roles?
El control de acceso basado en roles (RBAC) decide qué puede hacer cada usuario según los roles que tiene, como administrador, editor o visor. Los permisos se asignan a los roles y no a cada persona, así que cambiar lo que alguien puede hacer consiste en cambiarle el rol.
¿Cuál es la diferencia entre autenticación y autorización?
La autenticación comprueba quién es alguien, normalmente al iniciar sesión. La autorización decide qué puede ver y hacer esa persona una vez autenticada. El RBAC es una forma de autorización.
¿Basta con ocultar botones en la interfaz para restringir el acceso?
No. Cualquiera puede llamar directamente a tu API, así que ocultar un botón solo cambia lo que ve la gente. Cada petición que lea o cambie datos debe comprobarse en el servidor frente al rol del usuario y a la propiedad del registro.
¿Debo usar la seguridad a nivel de fila de Postgres?
La seguridad a nivel de fila permite que la propia base de datos imponga qué filas puede leer o escribir cada usuario, lo que es una red de seguridad sólida, sobre todo cuando el frontend habla directamente con la base de datos. Añade complejidad, así que muchas apps aplican los permisos en el código del servidor y usan la seguridad a nivel de fila como capa adicional para las tablas sensibles.