Seguridad: Roles, GRANT y REVOKE
Hasta ahora cada consulta y cada ejercicio de este curso corrió como dueño de la base de datos: acceso total, sin restricciones. En un sistema real eso es un riesgo enorme —cualquiera con esa conexión puede leer, modificar o borrar cualquier cosa—. PostgreSQL resuelve esto con roles (quién se conecta) y privilegios (qué puede hacer cada uno), aplicando el principio de darle a cada quien exactamente lo que necesita, ni un permiso más.
👁 — vistas · Ing. Roy Carrasco, Facultad de Ingeniería de Sistemas · UAB
Scrollea para empezar — a la izquierda vas a ver la consola armarse sola, mientras leés a la derecha.
-- todavía no escribimos nada
Todo el mundo entra como el dueño
En todos los talleres anteriores te conectaste como el superusuario de la base —acceso total, sin excepción—. En un sistema real con varias personas (aplicaciones, analistas, pasantes) eso significa que cualquiera de ellas podría, por accidente o a propósito, borrar una tabla entera.
Un rol nuevo, sin privilegios todavía
CREATE ROLE crea una identidad dentro de la base de datos. Por sí sola, no le da ningún permiso: ni siquiera puede conectarse. Es solo un nombre al que después le vamos a otorgar (o quitar) capacidades, una por una.
Un rol que sí puede conectarse
Sin LOGIN, un rol existe pero nadie puede iniciar sesión con él —sirve solo como una "etiqueta" de permisos para agrupar (lo vas a ver en el paso 05). Con WITH LOGIN PASSWORD '...', en cambio, alguien puede conectarse a la base usando esa identidad.
Consultar quién puede hacer qué
pg_roles es una vista del sistema: lista todos los roles que existen, con columnas como rolcanlogin (¿puede conectarse?) y rolsuper (¿es superusuario?). lector no puede conectarse todavía; editor sí; postgres es el único superusuario.
Un rol puede heredar de otro
GRANT editor TO admins; no le da una tabla ni una acción —hace que admins se vuelva miembro de editor, heredando automáticamente todos los privilegios que editor tenga en este momento, y los que reciba en el futuro.
Cambiar de identidad dentro de la misma sesión
SET ROLE lector; hace que, desde este punto, PostgreSQL trate el resto de la sesión como si fueras lector —no el superusuario que abrió la conexión—. current_user confirma el cambio.
Volver a ser quien realmente sos
RESET ROLE; deshace el SET ROLE anterior y devuelve la sesión a su identidad original —acá, de vuelta a postgres. Todavía no le dimos ningún permiso a lector sobre ninguna tabla: eso es lo que sigue.
Practicá lo que viste
Antes de seguir a GRANT y REVOKE, confirmá que la diferencia entre crear un rol y darle permisos quedó clara.
Justo después de ejecutar CREATE ROLE lector; y nada más, ¿qué puede hacer ese rol sobre las tablas de la base?
Sobre la creación y consulta de roles.
1. Para que un rol pueda conectarse directamente a la base de datos, hay que crearlo con la palabra clave .
2. La vista del sistema que lista todos los roles existentes, con columnas como rolcanlogin, se llama
.
Clasifica cada sentencia según si administra el rol en sí, o los permisos que ese rol tiene sobre un objeto.
-- todavía no escribimos nada
lector todavía no puede leer nada
Ya como lector (con SET ROLE), intentar un simple SELECT sobre productos falla. No es un error de sintaxis: PostgreSQL directamente le niega el acceso a la tabla, porque nadie le otorgó ese permiso todavía.
Otorgar el permiso de lectura
GRANT SELECT ON productos TO lector; le da a lector exactamente un permiso: leer esa tabla. Nada de escribir, nada de otras tablas —solo esto.
El mismo SELECT, distinto resultado
La misma consulta que falló en el paso 01 ahora devuelve filas. El único cambio fue el GRANT del paso anterior —el rol es el mismo, la consulta es la misma.
SELECT no incluye INSERT
Todavía como lector, un INSERT falla —el GRANT SELECT del paso 02 no le dio ningún otro privilegio. Cada acción (SELECT, INSERT, UPDATE, DELETE) se otorga por separado.
GRANT admite una lista
Para editor no hace falta un GRANT por cada permiso: GRANT SELECT, INSERT, UPDATE ON productos TO editor; le otorga los tres de una sola vez.
Quitar un permiso ya otorgado
REVOKE SELECT ON productos FROM lector; hace exactamente lo contrario de GRANT: le retira ese permiso puntual a lector, sin tocar los permisos de ningún otro rol.
lector vuelve a no poder leer
El mismo SELECT que funcionaba en el paso 03 vuelve a fallar. REVOKE deshizo el GRANT del paso 02 —los permisos de PostgreSQL no son "todo o nada": se pueden otorgar y retirar en cualquier momento, uno por uno.
Practicá lo que viste
Emparejá cada instrucción con lo que hace, y confirmá por qué un permiso no arrastra a los demás.
Une cada término con su descripción.
editor tiene GRANT SELECT, INSERT, UPDATE ON productos. Si intenta DELETE FROM productos WHERE id = 1;, ¿qué pasa?
Ejercicios de razonamiento
En estas preguntas no se te pide recordar sintaxis: se te da un escenario, y debés razonar cuál sería la respuesta correcta antes de comprobarla.
Un nuevo integrante del equipo va a generar reportes leyendo las tablas de ventas todos los días. Nunca necesita modificar ni un solo dato.
¿Qué le das?
Alguien del equipo deja el proyecto esta semana. Todavía tiene un rol activo con LOGIN y varios permisos otorgados.
¿Qué es lo mínimo que hay que hacer con su rol?
Estás decidiendo cuántos permisos otorgarle a cada rol nuevo que creás.
Completá la regla general:
Cada rol debería tener exactamente los permisos que necesita para su tarea, ni uno más — esto se conoce como el principio de .
Actividades de repaso
Un repaso integrador de todo el módulo. Cada actividad se corrige al instante; tu progreso se guarda automáticamente en este navegador.
¿Qué diferencia real hay entre CREATE ROLE lector; y CREATE ROLE editor WITH LOGIN PASSWORD '...';?
Un rol recién creado con CREATE ROLE, sin ningún GRANT posterior, ya puede leer cualquier tabla de la base.
¿Qué hace exactamente SET ROLE lector; dentro de una sesión?
¿Qué instrucción se usa para quitarle un permiso ya otorgado a un rol?
GRANT editor TO admins; ¿qué significa exactamente?
De DDL a Seguridad: todo el camino recorrido
Esta guía cierra el bloque de SQL relacional del curso. Antes de pasar a NoSQL, un repaso rápido de todo lo que ya sabés hacer con PostgreSQL:
| Bloque | Qué aprendiste |
|---|---|
| 1. DDL y restricciones | CREATE TABLE, tipos de datos, PRIMARY KEY/FOREIGN KEY/CHECK/NOT NULL/UNIQUE — el esqueleto de una base bien diseñada. |
| 2. DML y SELECT básico | INSERT/UPDATE/DELETE, WHERE/ORDER BY/LIMIT — cargar y consultar datos día a día. |
| 3. JOINs y subconsultas | Combinar filas de varias tablas relacionadas, y consultas anidadas dentro de otras. |
| 4. Agregación y vistas | GROUP BY/HAVING para resumir datos, CREATE VIEW para guardar una consulta reutilizable. |
| 5. Funciones de ventana e índices | ROW_NUMBER/RANK/LAG/LEAD sin colapsar filas, e índices + EXPLAIN para que las consultas grandes sean rápidas. |
| 6. Transacciones | ACID, aislamiento y bloqueos, para que operaciones concurrentes no se pisen entre sí. |
| 7. Procedimientos, funciones y triggers | Lógica que vive dentro de la base de datos, a veces disparada automáticamente. |
| 8. Seguridad: roles y permisos | Quién puede hacer qué, aplicando el principio de mínimo privilegio. |
Con esto se cierra el bloque de SQL relacional. La próxima guía cambia de mundo: MongoDB y las bases de datos de documentos, donde los datos no viven en filas rígidas sino en estructuras flexibles. La meta del curso no es elegir "SQL o NoSQL" —es saber decidir qué dato va en cuál motor y por qué: los datos transaccionales y estructurados (pedidos, pagos, inventario) van a seguir viviendo en PostgreSQL, mientras que los datos flexibles o de alto volumen (catálogos, logs, reseñas) van a pasar a MongoDB, ambos usados juntos desde una misma aplicación en el Proyecto Integrador final.
Cheat Sheet
| Forma | Para qué sirve |
|---|---|
CREATE ROLE nombre; | Crea un rol sin ningún privilegio, ni siquiera de conexión. |
CREATE ROLE nombre WITH LOGIN PASSWORD '...'; | Crea un rol que puede conectarse directamente a la base. |
GRANT privilegio ON tabla TO rol; | Otorga un permiso específico (SELECT, INSERT, UPDATE, DELETE) sobre un objeto. |
REVOKE privilegio ON tabla FROM rol; | Retira un permiso otorgado antes, sin afectar a otros roles. |
GRANT rol_a TO rol_b; | rol_b se vuelve miembro de rol_a y hereda todos sus privilegios (membresía). |
SET ROLE nombre; | Cambia la identidad efectiva de la sesión actual. |
RESET ROLE; | Vuelve al rol original de la sesión, antes de cualquier SET ROLE. |
SELECT * FROM pg_roles; | Lista todos los roles de la base y sus atributos (rolcanlogin, rolsuper, ...). |
ALTER ROLE nombre WITH NOLOGIN; | Le quita a un rol la capacidad de conectarse, sin eliminarlo. |
GRANT USAGE ON SEQUENCE nombre_seq TO rol; | Necesario además de INSERT cuando la tabla usa una columna SERIAL — un detalle que se pisa la primera vez. |
¿Sabías que...?
🔒 El mínimo privilegio no es solo de bases de datos
Es una práctica de seguridad general: permisos de archivos en un sistema operativo, alcance de una API key, roles de IAM en AWS/GCP. La misma pregunta — "¿de verdad necesita esto?" — aplica en todos esos contextos, no solo en SQL.
👥 PostgreSQL ya trae roles predefinidos
Además de los que vos creás, PostgreSQL incluye roles como pg_read_all_data o pg_monitor, pensados para otorgarse por membresía (igual que GRANT editor TO admins;) en vez de armar permisos equivalentes a mano, tabla por tabla.
🎯 GRANT también puede ser por columna
GRANT SELECT (nombre, precio) ON productos TO rol; le da acceso solo a esas dos columnas, no a la tabla entera — útil cuando una tabla mezcla datos públicos (nombre, precio) con datos sensibles (costo interno, margen) que no todos deberían ver.