"RLS" y "multi-inquilino" se encuentran uno al lado del otro en casi todo el contenido ya publicado sobre el tema, una elección legítima para muchas arquitecturas SaaS, pero que no es la elección de Aurabase para separar a sus propios clientes entre sí. Esta publicación explica la diferencia con el motor de aprovisionamiento real y las políticas RLS realmente aplicadas, no una descripción de marketing simplificada. Para obtener una descripción general de lo que cubre el motor de Postgres administrado de Aurabase más allá del aislamiento, consulte la documentación de la base de datos .
Lo esencial
- Entre proyectos, Aurabase aísla mediante la base dedicada de Postgres, nunca solo mediante RLS: cada proyecto tiene su propia base física, en un clúster CNPG dedicado (nivel de empresa) o en el clúster CNPG de su propia organización (libre/profesional/equipo), nunca compartido con otra organización.
- El RLS (
auth.uid(),auth.role(),auth.jwt()) permanece activo y recomendado dentro de su base, para aislar a sus propios usuarios, la misma convención que Supabase. service_roley los roles de administración basados en proyectos evitan RLS por diseño (BYPASSRLS): una elección arquitectónica supuesta para las operaciones del servidor, no una falla.- Una regresión ya corregida en este repositorio (derechos
PUBLICconcedidos por error en esquemas compartidos antiguos) ilustra concretamente por qué un borde en el nivel base resiste mejor que un borde puramente de aplicación.
El atajo que toman la mayoría de las guías RLS multiinquilino
El patrón más documentado para Postgres multiinquilino consta de tres líneas: una base única, una columna tenant_id en cada tabla, una política RLS que compara esta columna con un valor extraído del JWT. Es económico (un conjunto de conexiones, un diagrama, una sola instancia para ejecutar) y funciona bien cuando los inquilinos son numerosos, pequeños y de bajo interés individual.
El compromiso es real: el límite entre dos clientes se convierte en una expresión SQL, evaluada tabla por tabla. Una política olvidada en una nueva tabla, una conexión ejecutándose con un rol de superusuario, un script de depuración lanzado en vivo: cada uno de estos incidentes, por trivial que sea su funcionamiento, puede exponer silenciosamente las líneas de todos los inquilinos al mismo tiempo. El límite de seguridad y el límite técnico (la base) son entonces exactamente lo mismo.
Esta no es una mala elección en sí misma: es el compromiso correcto para muchos productos. El objetivo de esta publicación está en otra parte: este no es el compromiso que Aurabase ha hecho para separar a sus propios clientes (proyectos completos, potencialmente con diferentes requisitos de cumplimiento) entre sí.
Dos arquitecturas, nunca una base compartida entre proyectos
Desde una reciente consolidación del aprovisionador (marcado en el código como "Tarea 12"), un proyecto de Postgres activo en Aurabase cae exactamente bajo dos arquitecturas: los modelos antiguos con una base realmente compartida entre varios proyectos se han eliminado de la ruta de aprovisionamiento.
El nivel del proyecto decide cuál de los dos se aplica, y es el código el que decide, no una casilla marcada en un panel:
| Dimensiones | Totalmente Dedicada (empresa) | SharedClusterDedicated (gratis/pro/equipo) |
|---|---|---|
| Clúster CNPG | Dedicado a este proyecto | Compartido, pero nunca entre dos organizaciones. |
| base de datos postgres | aplicación, solo proyecto en ella | project_<uuid>, uno por proyecto en el clúster |
| Iniciar sesión en PostgreSQL | Un único proyecto en el cluster: sin riesgo de membresía cruzada | Inicio de sesión por proyecto (F-013), miembro de sus únicos roles inquilino_<uuid> |
En ambas arquitecturas, la base o el clúster nunca alberga dos organizaciones diferentes, por lo que la pregunta no es "¿sus datos están aislados" sino "¿su proyecto tiene cómputo CloudNativePG para sí mismo o lo comparte con otros proyectos de la misma organización?".
Esta consolidación de dos arquitecturas es reciente: el código anteriormente llevaba dos rutas adicionales: un "maestro compartido" donde varios proyectos coexistían en la misma base de datos, aislados sólo por diagrama, y una variante postgrest_dedicated_shared_db. Una migración dedicada los eliminó y apretó la restricción de la tabla projects a solo los dos valores restantes, precisamente porque el modelo de esquema compartido fue la fuente del error que se describe a continuación.
Por qué una base dedicada supera a una EPIRB compartida entre clientes
Una base de datos de Postgres separada es un límite a nivel de conexión, no un límite a nivel de fila. Una función de aplicación conectada a la base de datos del proyecto A simplemente no puede consultar las tablas del proyecto B: no tiene una sesión abierta. Esta propiedad se mantiene incluso si una política RLS está mal escrita, falta en una tabla o es omitida por una función importante: el peor de los casos permanece confinado dentro de una única base de datos.
Este depósito también lleva la huella de un error real que ilustra el riesgo contrario. Según el antiguo modelo de esquema compartido (ya retirado), provision_postgres_schema otorgó por error derechos a GRANT ALL ... TO PUBLIC para cada esquema de proyecto; PUBLIC aplicó a todos los roles en la base de datos sin condiciones de membresía, un inicio de sesión aislado por proyecto podría leer y escribir en el esquema de otro. Una migración correctiva (066) eliminó estos derechos del existente.
El parche no agregó una política RLS más para tapar la fuga: eliminó la posibilidad misma de que dos proyectos compartieran una base de datos. Sobre las dos arquitecturas actuales, un comentario de provisioning.rs lo documenta en blanco y negro: “cada proyecto ya tiene su propia base de datos física de Postgres”. Un límite de nivel básico hace que toda una clase de errores de este tipo sean simplemente inalcanzables, en lugar de depender de que cada política esté siempre escrita correctamente.
Un parche del 23 de agosto de 2026 va en la misma dirección: un REVOKE ALL ON SCHEMA public colocado incondicionalmente por el aprovisionador se condicionó a la topología, porque solo proporcionaba un aislamiento real en el antiguo modelo de base de datos compartida; en las dos arquitecturas actuales, bloqueaba sin beneficio la importación de volcados de SQL que hacen referencia explícita a public.<table>.
EPIRB permanece ahí: en su base de datos, para sus usuarios
Nada de lo anterior inutiliza la EPIRB: simplemente cambia de piso. Una vez en la base de datos de su proyecto, Aurabase expone exactamente la convención PostgREST adoptada por Supabase: tres funciones SQL que leen las notificaciones JWT establecidas por la puerta de enlace en request.jwt.claims.
Estos ayudantes se utilizan en las políticas reales de Aurabase, no solo se documentan para la suya. Aquí está la política que protege storage_objects, tal como se coloca en el repositorio (formateada en varias líneas para su lectura):
En su propio esquema project_<uuid>, el que contiene las tablas de su aplicación, Aurabase deliberadamente no coloca ninguna política en su nombre; el código lo documenta como un "modelo Supabase": el RLS de sus tablas sigue siendo su responsabilidad, con las mismas funciones, la misma sintaxis.
service_role omite RLS: por diseño, no por accidente
Postgres ofrece de forma nativa un atributo de rol , BYPASSRLS, que ignora todas las políticas. Aurabase lo utiliza voluntariamente en dos familias de roles: aura_service_role (el rol de servidor, nunca expuesto en el lado del navegador) y el rol de administración específico de cada proyecto, utilizado durante operaciones DDL como ALTER SCHEMA ... OWNER TO.
El rol que atiende sus solicitudes anon/authenticated — tenant_<uuid> — no tiene ningún BYPASSRLS: el RLS se le aplica normalmente, sin excepción. Como beneficio adicional, los diagramas del sistema específicos de cada proyecto (_auth, _storage, _platform) reciben un RLS activado sin política; por lo tanto, un rechazo total de forma predeterminada para cualquier función que no sea de omisión, una defensa en profundidad en caso de que una ruta de aplicación acceda a ella algún día por error.
Omitir el RLS con una función de servidor elevada no es exclusivo de Aurabase: es la misma construcción que service_role en el lado de Supabase. El punto no es evitar BYPASSRLS, sino nunca otorgarlo a un rol accesible desde un cliente y limitarlo a un solo proyecto.
Esta función de servidor es parte de una postura más amplia (roles predefinidos, RBAC personalizado, registros de auditoría) que se detalla en la página Seguridad y RBAC.
En un clúster compartido, la base de datos no hace todo el trabajo sola
En el nivel SharedClusterDedicated, varios proyectos de la misma organización coexisten en un único clúster CNPG. La base de datos física ya separa los proyectos entre sí, pero los roles de PostgreSQL (ellos) son objetos globales para el clúster, no para la base de datos. Por lo tanto, Aurabase agrega una capa: un inicio de sesión de PostgreSQL separado por proyecto.
Cada proyecto se conecta con su propio inicio de sesión, miembro únicamente de sus propios roles tenant_<uuid> / tenant_<uuid>_admin, nunca los de otro proyecto en el mismo clúster. La base de datos ya aísla los datos; Este inicio de sesión por proyecto también aísla la identidad que se conecta a él, de modo que un incidente en un proyecto no le da a su inicio de sesión ninguna membresía para heredar a otro.
RLS solo o base dedicada: cómo decidirse por su propio SaaS
La elección de Aurabase no es una regla universal: es un compromiso para un caso específico: aislar a los clientes entre sí, potencialmente con diferentes requisitos de cumplimiento, en una plataforma que no controlan. Si está creando su propio SaaS, le surge la misma pregunta, en una escala diferente.
- RLS con
tenant_iden una base compartida: relevante cuando sus inquilinos son numerosos, individualmente de baja participación y el costo de una base por inquilino sería desproporcionado. Pruebe cada política conpg_prove, en cada tabla, sin excepción. - Base o diagrama dedicado: relevante siempre que un inquilino tenga su propio problema de cumplimiento (salud, recursos humanos, sector público), un volumen que justifique el aislamiento del rendimiento o el costo de una fuga entre dos clientes específicos sería desproporcionado con el costo de la infraestructura adicional.
El nivel de precios de Aurabase aplica este mismo arbitraje a sus propios clientes: base compartida por organización por defecto, cluster dedicado cuando el desafío del proyecto lo justifica. Para patrones RLS dentro de su propia base de datos (propiedad, multiinquilino por organización, jerarquía de roles), la guía RLS en producción detalla los tres casos con pruebas pgTAP. Y si la API generada automáticamente en su diagrama le interesa más allá de REST, la comparación en pg_graphql versus Hasura y PostGraphile cubre la otra mitad de la superficie de Postgres expuesta por Aurabase.