DBAtlas · Atlas de operaciones de bases de datos

Configurar el aislamiento de inquilinos con row-level security

PostgreSQLSeguridad

Comando

ALTER TABLE app.orders ENABLE ROW LEVEL SECURITY;
-- Make the table owner subject to the policy too
ALTER TABLE app.orders FORCE ROW LEVEL SECURITY;

CREATE POLICY orders_tenant_isolation ON app.orders
  FOR ALL
  TO app_readwrite
  USING (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::int)
  WITH CHECK (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::int);

-- The application sets the tenant at the start of every transaction (pooler-friendly)
BEGIN;
SET LOCAL app.tenant_id = '42';
SELECT * FROM app.orders;
COMMIT;

-- Configured policies
SELECT schemaname, tablename, policyname, roles, cmd, qual, with_check
FROM pg_policies
WHERE tablename = 'orders';

Qué hace

Habilita RLS en la tabla y define una política que filtra las filas por el id de inquilino de una variable de sesión (USING) y bloquea las escrituras para otro inquilino (WITH CHECK).

Cuándo usarlo

Para imponer el aislamiento de datos en la base de datos en aplicaciones multiinquilino en lugar de depender del código de la aplicación.

Precaución

Los superusuarios y los roles con el atributo BYPASSRLS siempre omiten las políticas; el propietario de la tabla solo está sujeto a ellas con FORCE ROW LEVEL SECURITY. Con RLS habilitado y sin ninguna política coincidente, el resultado está vacío (sin error). current_setting(..., true) devuelve NULL cuando la variable no está definida; NULLIF evita que la cadena vacía que queda tras RESET falle como ''::int. Los usuarios pueden cambiar app.tenant_id con SET; solo una capa de aplicación de confianza debe definirlo y los usuarios finales no deben tener acceso SQL. Con un pooler en modo transaction, use SET LOCAL en lugar de SET. Indexe la columna tenant_id usada en la política. pg_dump falla cuando se ejecuta como un usuario sujeto a RLS; haga los backups con un rol BYPASSRLS.

Abrir en DBAtlas →

Relacionado