Compartir a través de


Seguridad de nivel de fila en Azure Cosmos DB for PostgreSQL

SE APLICA A: Azure Cosmos DB for PostgreSQL (con tecnología de la extensión de base de datos de Citus en PostgreSQL)

Las directivas de seguridad de nivel de fila de PostgreSQL restringen qué usuarios pueden modificar o acceder a las filas de tabla. La seguridad de nivel de fila puede resultar especialmente útil en un clúster multiinquilino. Permite que los inquilinos individuales tengan acceso completo de SQL a la base de datos mientras ocultan la información de cada inquilino de otros inquilinos.

Implementación para aplicaciones multiinquilino

Podemos implementar la separación de los datos de inquilino mediante una convención de nomenclatura para los roles de base de datos que se vinculan a directivas de seguridad de nivel de fila de tabla. Asignaremos a cada inquilino un rol de base de datos en una secuencia numerada: tenant1, tenant2, etc. Los inquilinos se conectarán a Azure Cosmos DB for PostgreSQL con estos roles independientes. Las directivas de seguridad de nivel de fila pueden comparar el nombre de rol con los valores de la columna de distribución tenant_id para decidir si se debe permitir el acceso.

Aquí se muestra cómo aplicar el enfoque en una tabla de eventos simplificada distribuida por tenant_id. En primer lugar, cree los roles tenant1 y tenant2. A continuación, ejecute los siguientes comandos SQL como usuario administrador citus:

CREATE TABLE events(
  tenant_id int,
  id int,
  type text
);

SELECT create_distributed_table('events','tenant_id');

INSERT INTO events VALUES (1,1,'foo'), (2,2,'bar');

-- assumes that roles tenant1 and tenant2 exist
GRANT select, update, insert, delete
  ON events TO tenant1, tenant2;

Como está, cualquier persona con permisos seleccionados para esta tabla puede ver ambas filas. Los usuarios de cualquiera de los inquilinos pueden ver y actualizar la fila del otro inquilino. Podemos resolver la pérdida de datos con directivas de seguridad de tabla de nivel de fila.

Cada directiva consta de dos cláusulas: USING y WITH CHECK. Cuando un usuario intenta leer o escribir filas, la base de datos evalúa cada fila con respecto a estas cláusulas. PostgreSQL comprueba las filas de tabla existentes en la expresión especificada en la cláusula USING y las filas que se crearían a través de INSERT o UPDATE en la cláusula WITH CHECK.

-- first a policy for the system admin "citus" user
CREATE POLICY admin_all ON events
  TO citus           -- apply to this role
  USING (true)       -- read any existing row
  WITH CHECK (true); -- insert or update any row

-- next a policy which allows role "tenant<n>" to
-- access rows where tenant_id = <n>
CREATE POLICY user_mod ON events
  USING (current_user = 'tenant' || tenant_id::text);
  -- lack of CHECK means same condition as USING

-- enforce the policies
ALTER TABLE events ENABLE ROW LEVEL SECURITY;

Ahora, los roles tenant1 y tenant2 obtienen resultados diferentes para sus consultas:

Conectado como tenant1:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         1 │  1 │ foo  │
└───────────┴────┴──────┘

Conectado como tenant2:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         2 │  2 │ bar  │
└───────────┴────┴──────┘
INSERT INTO events VALUES (3,3,'surprise');
/*
ERROR:  new row violates row-level security policy for table "events_102055"
*/

Pasos siguientes