En una aplicación multi-tenant, varios clientes comparten una misma plataforma, pero sus datos deben permanecer estrictamente aislados. Esta separación no puede depender solo de la lógica de la aplicación. Cuando una consulta se construye de forma incorrecta, un filtro se omite o un servicio reutiliza credenciales con demasiados privilegios, el riesgo de exposición entre clientes aumenta.
Row Level Security, o RLS, permite reforzar ese aislamiento directamente en PostgreSQL. Su objetivo es controlar qué filas puede consultar, insertar, actualizar o eliminar cada usuario, rol o cliente, aplicando políticas en la propia base de datos. De este modo, la seguridad se acerca al dato y no queda limitada al código de la aplicación.
En entornos empresariales, RLS en PostgreSQL resulta especialmente relevante para plataformas SaaS, portales B2B, soluciones internas compartidas y arquitecturas donde diferentes unidades, clientes o grupos deben operar sobre una misma base de datos sin acceder a información que no les corresponde.
Qué es RLS en PostgreSQL y por qué encaja en arquitecturas multi-tenant
RLS es un mecanismo de seguridad a nivel de fila. A diferencia de los permisos tradicionales, que suelen controlar el acceso a tablas, esquemas o funciones, RLS permite aplicar una condición sobre cada fila de una tabla. Si una fila no cumple la política definida para el rol que ejecuta la consulta, PostgreSQL la excluye de la operación.
En una arquitectura multi-tenant, esta capacidad permite asociar cada registro a un identificador de cliente, organización o tenant. Después, las políticas de RLS verifican que el contexto de ejecución solo pueda operar con las filas que pertenecen a ese tenant.
Este enfoque no sustituye a un diseño de permisos correcto, ni a una arquitectura segura de aplicación. Sin embargo, añade una capa de control muy útil cuando se desea reducir el impacto de errores en consultas, APIs o servicios que acceden a la base de datos.
Modelos habituales de multi-tenancy en PostgreSQL
Antes de aplicar RLS, conviene revisar el modelo de aislamiento de datos que utiliza la plataforma. PostgreSQL puede emplearse en diferentes aproximaciones multi-tenant, cada una con implicaciones distintas de operación, seguridad y mantenimiento.
Una base de datos por cliente
Este modelo ofrece un aislamiento muy claro, pero puede incrementar la complejidad operativa cuando el número de clientes crece. La gestión de actualizaciones, copias de seguridad, monitorización y despliegues requiere una estrategia específica.
Un esquema por cliente
Separar tenants por esquemas puede facilitar cierta organización lógica, aunque también implica gestionar permisos, migraciones y objetos duplicados. Es una opción intermedia que puede ser adecuada en algunos escenarios empresariales.
Tablas compartidas con identificador de tenant
En este modelo, varios clientes comparten las mismas tablas y cada fila incluye una columna de identificación, como tenant_id, organization_id o customer_id. Es aquí donde RLS cobra especial importancia, porque permite definir políticas que filtren las filas según ese identificador.
Cómo funciona RLS en tablas compartidas
Para utilizar RLS, la tabla debe incluir una columna que permita relacionar cada fila con su tenant. Después, se habilita la seguridad a nivel de fila en la tabla y se crean políticas que indiquen qué condiciones deben cumplirse para cada operación.
ALTER TABLE facturas ENABLE ROW LEVEL SECURITY;
Una política básica podría permitir que un rol de aplicación acceda únicamente a las filas cuyo tenant_id coincida con el tenant definido en el contexto de la sesión.
CREATE POLICY facturas_por_tenant
ON facturas
USING (tenant_id = current_setting(‘app.tenant_id’)::uuid)
WITH CHECK (tenant_id = current_setting(‘app.tenant_id’)::uuid);
La cláusula USING controla qué filas son visibles o modificables para operaciones como SELECT, UPDATE o DELETE. La cláusula WITH CHECK verifica que las nuevas filas insertadas o actualizadas cumplan también la condición definida. En una aplicación multi-tenant, ambas partes son importantes: no basta con evitar que un cliente lea datos de otro; también debe impedirse que inserte o modifique registros asociados a un tenant incorrecto.
Políticas, roles y contexto de sesión
Una implementación empresarial de RLS debe definir con claridad la relación entre roles de base de datos, usuarios de aplicación y contexto de tenant. No existe un único patrón válido para todos los casos, pero sí varios criterios que ayudan a reducir riesgos.
Definir roles con privilegios mínimos
El rol que utiliza la aplicación no debería tener más permisos de los necesarios. RLS no debe convertirse en una excusa para conceder privilegios amplios. Es recomendable combinar GRANT, REVOKE y políticas RLS de forma coherente, de modo que el acceso esté limitado tanto a nivel de objeto como a nivel de fila.
Separar roles administrativos y roles de aplicación
Los roles administrativos, de mantenimiento o de migración deben gestionarse de forma independiente. En PostgreSQL, determinados roles pueden eludir las políticas RLS, por lo que conviene controlar cuidadosamente atributos como BYPASSRLS y evitar que estén disponibles en cuentas de uso ordinario.
Usar variables de sesión con control estricto
Una práctica habitual consiste en establecer el tenant activo en una variable de sesión, por ejemplo app.tenant_id, al inicio de cada petición o transacción. Esta variable debe fijarse desde una capa de confianza y no quedar expuesta a manipulación directa por parte del usuario final.
En entornos con pools de conexiones, este punto requiere especial atención. Si una conexión se reutiliza entre peticiones, el contexto de tenant debe inicializarse y limpiarse correctamente para evitar heredar valores de una solicitud anterior.
Buenas prácticas para implementar RLS en PostgreSQL
- Identificar de forma explícita las tablas que contienen datos multi-tenant.
- Asegurar que todas las tablas compartidas incluyen una clave de tenant coherente.
- Crear políticas diferenciadas para lectura, inserción, actualización y borrado cuando el caso de uso lo requiera.
- Aplicar el principio de mínimo privilegio a los roles de base de datos.
- Validar el comportamiento de RLS con pruebas automatizadas por tenant, rol y operación.
- Revisar el impacto de las políticas en el rendimiento de consultas críticas.
- Documentar las políticas y su relación con los flujos de negocio de la aplicación.
- Controlar de forma estricta los roles con capacidad de bypass o administración.
Probar escenarios positivos y negativos
Las pruebas no deben limitarse a comprobar que un usuario ve sus propios datos. También deben verificar que no puede acceder a filas de otros tenants, que no puede insertar registros con un tenant_id incorrecto y que las operaciones de actualización o borrado respetan las políticas definidas.
Revisar índices y planes de consulta
Las políticas RLS añaden condiciones a las consultas. Por ello, es importante contar con índices adecuados sobre las columnas utilizadas en las políticas, como tenant_id. En tablas grandes, una mala estrategia de indexación puede afectar al rendimiento y dificultar la escalabilidad de la plataforma.
Evitar dependencias opacas en la lógica de aplicación
RLS debe complementar la lógica de aplicación, no ocultarla. El código debe seguir siendo claro respecto al tenant con el que opera cada petición. Si la aplicación depende de comportamientos implícitos difíciles de auditar, la seguridad puede volverse más compleja de mantener.
Riesgos frecuentes al aplicar RLS
Aunque RLS es una funcionalidad potente, algunos errores de diseño pueden reducir su efectividad. Entre los más habituales se encuentran el uso de roles excesivamente privilegiados, la ausencia de políticas WITH CHECK, el tratamiento incorrecto del contexto de sesión en pools de conexiones y la falta de pruebas específicas de aislamiento.
También conviene tener en cuenta que RLS no corrige por sí solo problemas de autorización en la capa de aplicación. Por ejemplo, una API debe seguir validando qué acciones puede realizar cada usuario dentro de su tenant. RLS refuerza el aislamiento de datos, pero no sustituye el modelo completo de permisos funcionales.
RLS como capa de defensa para plataformas empresariales
Para empresas que operan aplicaciones multi-tenant sobre PostgreSQL, RLS permite trasladar una parte crítica del control de acceso al motor de base de datos. Esta aproximación ayuda a reducir riesgos, mejora la consistencia de las reglas de aislamiento y facilita que el acceso a los datos esté gobernado por políticas explícitas.
La clave está en diseñar las políticas desde el inicio, integrarlas con la gestión de roles, probarlas de forma sistemática y revisarlas cuando evolucionen los modelos de datos o los requisitos de negocio. En arquitecturas empresariales, esa disciplina marca la diferencia entre una configuración funcional y un modelo de seguridad mantenible.
Preguntas frecuentes sobre RLS en PostgreSQL
RLS ayuda a controlar qué filas puede consultar o modificar cada cliente, usuario o rol dentro de tablas compartidas, reforzando el aislamiento de datos entre tenants.
No. RLS debe combinarse con una gestión adecuada de roles, permisos sobre objetos y controles de autorización en la aplicación. Es una capa adicional de seguridad a nivel de fila.
En escenarios multi-tenant suele ser recomendable, porque permite validar que las filas insertadas o actualizadas cumplen la condición de tenant definida por la política.
El contexto de tenant debe establecerse y limpiarse correctamente en cada petición o transacción para evitar que una conexión reutilizada conserve valores anteriores.
Puede influir en el plan de consulta, ya que añade condiciones de filtrado. Por eso conviene revisar índices, consultas críticas y pruebas de carga en tablas relevantes.
¿Su empresa necesita reforzar el aislamiento de datos en PostgreSQL con un enfoque seguro, escalable y adaptado a sus aplicaciones multi-tenant? Contacte con el equipo de Hopla! y analice el siguiente paso para su proyecto tecnológico