¿Qué es la Seguridad a Nivel de Fila (RLS)?

Actualizado: septiembre de 2026

La seguridad a nivel de fila es un mecanismo de base de datos que filtra qué filas puede ver o modificar cada usuario, aplicado por políticas en cada consulta. El modelo mental es una cláusula WHERE invisible y obligatoria: la condición que de otro modo tendrías que recordar en cada consulta se vuelve una propiedad de la tabla misma — aplicada por el motor, en todo camino de acceso, incluidos los que el código de tu aplicación nunca ve.

Puntos clave

PreguntaRespuesta
Qué esControl de acceso por fila, aplicado por el propio motor de la base de datos
El modelo mentalUna cláusula WHERE que no se puede olvidar
El caso de uso estrellaAislamiento multi-tenant y datos por usuario, en la capa que las brechas no pueden saltarse
La letra chicaRoles de bypass, denegar por defecto, contexto de pooling — los detalles traicioneros son operativos
La falla que previeneUn filtro olvidado en el código de la aplicación = brecha entre tenants

RLS en diez líneas de SQL

CREATE TABLE invoices (
  tenant_id uuid NOT NULL,
  total     numeric(10,2)
);

ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;   -- desde aquí: denegar por defecto

CREATE POLICY tenant_isolation ON invoices
  USING      (tenant_id = current_setting('app.tenant')::uuid)   -- lo que puedes leer
  WITH CHECK (tenant_id = current_setting('app.tenant')::uuid);  -- lo que puedes escribir

-- Cada consulta ahora se comporta como si terminara con WHERE tenant_id = <el tuyo>.
-- Una consulta que olvida su filtro devuelve nada — no todo.

La misma garantía existe en bases de datos de documentos como control de acceso en la fila misma — cada objeto lleva su ACL, y la plataforma la aplica en cada solicitud:

// JavaScript / Node.js — Back4app JS SDK
// Row-level security as data: this row is readable by its owner, period
const note = new Parse.Object('Note');
note.set('text', 'Q3 salary planning');
note.setACL(new Parse.ACL(Parse.User.current())); // owner-only, on the row itself
await note.save();

// Later, any query by any user — the row exists only for its owner
const notes = await new Parse.Query('Note').find(); // others never see it

Qué hace el motor con una consulta

Cómo la seguridad a nivel de fila filtra una consultaDos usuarios distintos ejecutan la misma consulta contra una tabla; el motor aplica el predicado de la política de seguridad por fila antes de las condiciones del usuario, así que cada uno recibe solo las filas que su política permite.

SELECT * FROM invoices
(misma consulta, cualquier usuario)

Predicado de la política
aplicado por fila, primero

El tenant A ve
solo las filas del tenant A

El tenant B ve
solo las filas del tenant B

Dos usuarios distintos ejecutan la misma consulta contra una tabla; el motor aplica el predicado de la política de seguridad por fila antes de las condiciones del usuario, así que cada uno recibe solo las filas que su política permite.

USING vs. WITH CHECK, permisivas vs. restrictivas

ConceptoGobiernaRegla práctica
USINGLo que existe para ti: lecturas y filas elegibles para update/delete”¿Puedo verlo?”
WITH CHECKLo que puedes escribir: inserts y valores post-update”¿Puedo crearlo así?”
Políticas permisivas (por defecto)Combinadas con OR — cualquier coincidencia concedeConceder acceso
Políticas restrictivasSumadas con AND — todas deben pasarImponer límites obligatorios

Dos reglas de composición que vale la pena memorizar de la referencia de PostgreSQL: omitir WITH CHECK reutiliza USING para las escrituras, y al menos una política permisiva debe pasar antes de que las restrictivas siquiera se consulten — solo restrictivas significa que nadie entra.

Dónde está soportado RLS

Familia de motorMecanismo
PostgreSQL (9.5+) y derivadosCREATE POLICY — la implementación de referencia
SQL Server (2016+)Políticas de seguridad sobre funciones de predicado inline (filter + block)
SQL distribuido (CockroachDB, YugabyteDB)Políticas compatibles con PostgreSQL
Data warehouses en la nubePolíticas de acceso por fila, en el dialecto de cada proveedor
Bases de datos de documentosNo basadas en políticas — ACLs por objeto aplicadas por la capa de plataforma

La última fila es la que le interesa a este glosario: en las bases de documentos la frontera a nivel de fila típicamente es dato en la propia fila (ACLs) en lugar de un predicado en el motor — misma garantía, mecanismo distinto, detallado en el artículo de ingeniería de Back4app.

Los detalles traicioneros, por fin en un solo lugar

  • Sorpresas del denegar por defecto. Habilitar RLS sin ninguna política bloquea a todos excepto al dueño — la mitad de las historias de “RLS tumbó producción” son esto.
  • La matriz de bypass. Los superusuarios, los roles con BYPASSRLS y los dueños de tabla se saltan las políticas — define FORCE ROW LEVEL SECURITY si el dueño es también el usuario de la aplicación, y audita quién tiene qué.
  • Las views se evalúan como su dueño por defecto — una view sobre una tabla con RLS puede saltárselo en silencio, a menos que se cree con derechos del invocador (security_invoker en PostgreSQL).
  • Las constraints filtran existencia. Una violación de unicidad o de clave foránea puede revelar que una fila invisible existe — el canal encubierto documentado; trata la unicidad sobre valores protegidos en consecuencia.
  • Los errores pueden filtrar valores. Expresiones diseñadas para fallar con datos específicos (una división por cero cuando un valor oculto coincide) exfiltran a través de mensajes de error — la clase de side-channel que describe la documentación de SQL Server.
  • Los dumps y los pools tienen modos. Las herramientas de respaldo pueden necesitar el row security apagado para exportar todo; los poolers en modo transacción necesitan contexto con alcance de transacción (SET LOCAL), o los tenants se mezclan entre solicitudes.

Rendimiento: las políticas son código en el hot path

Tres reglas cubren la mayor parte de la experiencia de campo: indexa cada columna que una política referencia (el predicado corre antes que los filtros de tu propia consulta — sin índice, es un scan); mantén los predicados libres de joins, empujando los lookups a funciones o verificaciones de rol; y haz que las funciones por solicitud se evalúen una vez por consulta, no una vez por fila, envolviéndolas en una subconsulta escalar. Bien medido, RLS cuesta un solo dígito porcentual; mal medido, es la lentitud misteriosa en cada tabla que aseguraste.

Casos de uso comunes

  • SaaS multi-tenant. El caso canónico — aislamiento de tenants aplicado por debajo de la aplicación, donde un filtro olvidado no puede convertirse en brecha.
  • Datos por usuario. Mensajes, documentos, historiales médicos: los usuarios ven sus filas, punto.
  • Fronteras departamentales y regionales. Ventas ve su región; los auditores ven todo, en solo lectura — capas de políticas en acción.
  • Regímenes de compliance. Control de acceso demostrable en la capa de datos, que es donde les gusta a los auditores.
  • Acceso analítico compartido. Los analistas consultan réplicas de producción directamente, viendo solo lo que su rol permite — seguro porque la base de datos lo aplica, no el dashboard.

¿Deberías aplicar a nivel de fila? Matriz de decisión

Aplica con RLS/ACLs cuando…El filtrado en la aplicación puede bastar cuando…
Múltiples tenants o usuarios comparten tablasLa base de datos tiene exactamente un llamador confiable
Algo además de la app toca la base de datosSin herramientas de BI, sin SQL de admin, sin un segundo servicio
Un filtro olvidado significa brecha, no bugEl acotamiento es conveniencia, no seguridad
El compliance quiere prueba en la capa de datosLos datos no son sensibles
Quieres la frontera probada una vez, centralmenteDisfrutas auditar cada consulta para siempre

La síntesis honesta de las dos columnas: mantén el acotamiento en la aplicación por legibilidad — y aplícalo en la base de datos de todos modos. La defensa en profundidad es todo el punto.

Limitaciones y trade-offs

  • Las políticas son invisibles por diseño — lo que convierte depurar el “¿dónde quedaron mis filas?” en una habilidad genuina; registra el contexto de sesión primero.
  • La autorización compleja desborda los predicados. Las reglas que necesitan estado de workflow o lógica entre entidades pertenecen a las capas de autorización de la aplicación, con RLS como respaldo.
  • La superficie operativa es real. La matriz de bypass, los modos de dump y el contexto de pooling son conocimiento operativo continuo, no configuración de una sola vez.
  • La evaluación por fila es un impuesto — pequeño cuando está bien diseñado, ilimitado cuando no.
  • Asegura filas, no columnas. Ocultar campos es seguridad a nivel de columna; combina ambas para un efecto a nivel de celda.

Seguridad a nivel de fila en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Su modelo a nivel de fila es el mecanismo de ACL-como-dato de las pestañas de arriba: cada objeto lleva su lista de acceso, los roles expresan tenants y equipos, y la plataforma aplica ambos en cada solicitud — SDKs, REST, GraphQL y el dashboard incluidos, con los permisos a nivel de clase como la capa restrictiva por encima. Es la garantía de la cláusula WHERE obligatoria, entregada sobre una base de datos de documentos, con la lista de detalles traicioneros de arriba absorbida por la plataforma en lugar de asignada a ti.

Preguntas frecuentes

¿Qué es la seguridad a nivel de fila en términos simples?

Una cláusula WHERE invisible y obligatoria. Adjuntas políticas a una tabla y la base de datos aplica sus condiciones a cada consulta automáticamente — cada usuario ve y modifica solo las filas que la política permite, sin importar qué consulta escriba o qué herramienta use. El filtro vive en la base de datos, así que ningún camino de código de la aplicación puede olvidarlo.

¿Cómo funciona la seguridad a nivel de fila?

Habilitas RLS en una tabla y creas políticas con predicados booleanos — típicamente comparando la columna de dueño o de tenant de la fila con el usuario actual o una variable de sesión. Al ejecutar la consulta, el motor evalúa el predicado por fila antes de tus propias condiciones, filtrando lecturas y bloqueando escrituras no permitidas. Con RLS habilitado y ninguna política, el comportamiento por defecto es denegar todo.

¿Cuál es la diferencia entre USING y WITH CHECK?

La dirección. USING filtra lo que existe para ti: filas visibles al SELECT y elegibles para UPDATE o DELETE. WITH CHECK valida lo que escribes: filas siendo insertadas y los valores nuevos tras un update. Si omites WITH CHECK, el predicado de USING aplica a ambos — pero las tablas donde los usuarios leen amplio y escriben estrecho necesitan los dos, configurados distinto.

¿Quién puede saltarse la seguridad a nivel de fila?

En PostgreSQL: los superusuarios, los roles con BYPASSRLS y — el que todos olvidan — el dueño de la tabla, a menos que definas FORCE ROW LEVEL SECURITY. Auditar esa matriz de bypass es parte de desplegar RLS; una política perfecta no protege nada si la aplicación se conecta como el dueño de la tabla.

¿La seguridad a nivel de fila afecta el rendimiento?

Puede — el predicado de la política se evalúa contra las filas candidatas en cada consulta. Las mitigaciones son consistentes en la experiencia de producción: indexa las columnas que tus políticas referencian, mantén los predicados libres de joins (usa funciones o roles de lookup) y haz que las funciones por solicitud se evalúen una vez por consulta, no una vez por fila. Una política sobre una columna sin índice es un table scan con credencial de seguridad.

¿Cuál es la diferencia entre RLS y el filtrado en la aplicación?

Dónde vive la frontera. El filtrado en la aplicación acota consultas en el código — flexible, pero duplicado en cada camino y evadido por cualquier cosa que hable con la base de datos directamente. RLS aplica en el motor, cubriendo todo camino de acceso, incluidas las herramientas de admin y otros servicios. El consenso es defensa en profundidad: acota en la aplicación por claridad, aplica en la base de datos por seguridad.

¿Cómo funciona RLS con connection pooling?

Con cuidado. Las aplicaciones con pool se conectan como un único usuario de base de datos, así que las políticas dependen de una variable de sesión por solicitud en lugar de la identidad de la conexión — definida al tomar la conexión, leída por la política, reseteada al devolverla. Con poolers en modo transacción, la variable debe tener alcance de transacción, o el contexto de un tenant se filtra a la siguiente solicitud en la misma conexión. Esta interacción es el bug de RLS más común en producción.

¿Cómo se prueban las políticas de seguridad a nivel de fila?

Suplanta cada rol y ejecuta las cuatro operaciones — select, insert, update, delete — verificando tanto lo que aparece como lo que se rechaza. Agrega los dos casos olvidados: el contexto sin definir (ninguna variable de tenant debería significar cero filas, no todas) y la matriz de bypass (dueño, superusuario, caminos de replicación). RLS se gana la confianza con pruebas adversariales, no con una política bien redactada.

Términos relacionados

Compara con

Lecturas recomendadas

¿Listo para construir tu backend?

Empieza tu proyecto en Back4app en minutos — base de datos, autenticación, APIs y Cloud Code incluidos. Sin tarjeta de crédito.

Escrito y revisado por Back4app Engineering, Back4app Engineering · Publicado el 2026-09-03