Patrones GRANT/REVOKE
Los privilegios de PostgreSQL son explícitos por defecto. Los nuevos objetos no otorgan automáticamente acceso a los roles de aplicación. Modela deliberadamente los privilegios de esquema, tabla, columna y secuencia.
Receta
-- Ruta de lectura de la aplicación
GRANT USAGE ON SCHEMA app TO app_readers;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_readers;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA app TO app_readers;
-- Ruta de escritura de la aplicación (más restringida)
GRANT USAGE ON SCHEMA app TO app_writers;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_writers;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA app TO app_writers;Cuándo usar esto: Cada esquema nuevo, cada migración que crea tablas y cada rol de microservicio nuevo.
Ejemplo de Trabajo
CREATE SCHEMA app AUTHORIZATION app_owner;
CREATE ROLE app_api LOGIN PASSWORD 'vault';
CREATE ROLE app_ro LOGIN PASSWORD 'vault';
GRANT app_readers TO app_ro;
GRANT app_writers TO app_api;
-- Nivel de tabla con restricción de columna
CREATE TABLE app.users (
id bigint PRIMARY KEY,
email text NOT NULL,
ssn_last4 char(4) -- sensible
);
GRANT SELECT (id, email) ON app.users TO app_ro;
GRANT SELECT, INSERT, UPDATE ON app.users TO app_api;
REVOKE ALL ON app.users FROM PUBLIC;
-- Verificar privilegios efectivos
SELECT grantee, privilege_type, column_name
FROM information_schema.column_privileges
WHERE table_schema = 'app' AND table_name = 'users';Lo que esto demuestra:
- Se requiere
USAGEde esquema antes del acceso a la tabla. GRANT SELECT (columnas)a nivel de columna oculta campos sensibles de los analistas.REVOKE ALL FROM PUBLICcierra el agujero dePUBLICpor defecto en clústeres nuevos (al endurecer la seguridad).
Análisis Profundo
Capas de Privilegios
| Objeto | Privilegios comunes | Notas |
|---|---|---|
| DATABASE | CONNECT, CREATE, TEMP | CREATE en DB permite nuevos esquemas |
| SCHEMA | USAGE, CREATE | CREATE permite objetos en el esquema |
| TABLE | SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER | TRUNCATE es distinto de DELETE |
| SEQUENCE | USAGE, SELECT, UPDATE | UPDATE necesario para nextval |
| FUNCTION | EXECUTE | Requerido para RPC desde la aplicación |
PUBLIC y ACLs por Defecto
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE myapp FROM PUBLIC;
GRANT CONNECT ON DATABASE myapp TO app_readers;- PostgreSQL otorga históricamente algunos derechos a
PUBLICen el esquemapublic. - Las bases endurecidas revocan
PUBLICy otorgan explícitamente a roles de grupo. ALTER DEFAULT PRIVILEGESmaneja objetos futuros (ver página dedicada).
Propiedad vs Privilegios
- El propietario del objeto omite los privilegios para sus objetos (excepto RLS).
- Las migraciones deben ejecutarse como
app_ownerNOLOGIN; la conexión en tiempo de ejecución es comoapp_api. REASSIGN OWNEDmueve la propiedad durante el cambio de nombre de roles.
Trampas Comunes
- Se olvidó
USAGEde esquema -permission denied for schema appa pesar del GRANT de tabla. Solución:GRANT USAGE ON SCHEMA app. - Secuencia no concedida -
INSERTfunciona con serial hasta que la secuencia se agota en una nueva fila. Solución:GRANT USAGE, SELECT ON SEQUENCE. ALL TABLESno incluye tablas futuras - La migración añade una tabla; la aplicación devuelve 403 hasta que se vuelve a ejecutar el GRANT. Solución:ALTER DEFAULT PRIVILEGESpara el rol migrator.- GRANT de columna +
SELECT *- La aplicación usaSELECT *y falla de forma inconsistente en columnas ocultas. Solución: Listas de columnas explícitas en las consultas de la aplicación. - Superusuario en la cadena de conexión - Los privilegios son irrelevantes; pesadilla de auditoría. Solución: Rol de aplicación de mínimo privilegio siempre.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Row-Level Security | Aislamiento de inquilino en esquema compartido | CRUD simple de un solo inquilino |
| Vistas como barrera de seguridad | Ocultar columnas/uniones de tablas base | Alto volumen de escritura a través de vistas |
Funciones SECURITY DEFINER | Operaciones elevadas controladas | Acceso de escritura amplio de la aplicación |
Preguntas Frecuentes
¿Es `GRANT ALL TABLES` suficiente?
Cubre solo las tablas actuales. Las secuencias, funciones y tablas futuras necesitan grants separados o privilegios por defecto.
¿Cómo auditar los grants?
information_schema.table_privileges, has_table_privilege(), o herramientas GUI. Incluir grants en las revisiones de SQL de migración.
¿`REVOKE CASCADE`?
Raro para tablas. DROP OWNED BY es la herramienta de limpieza masiva al desmantelar roles.
¿Claves foráneas entre esquemas?
El lado de referencia necesita el privilegio REFERENCES en la tabla referenciada; ambos esquemas necesitan USAGE.
Relacionado
- Conceptos Básicos de Roles - modelo de roles de grupo
- Privilegios por Defecto - grants automáticos en objetos nuevos
- Row-Level Security - filtros de fila encima de los grants
Versiones de Stack: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, y PostGIS 3.5+.