Partilhar via


Segurança em nível de linha no Azure Cosmos DB para PostgreSQL

APLICA-SE A: Azure Cosmos DB para PostgreSQL (alimentado pela extensão de banco de dados Citus para PostgreSQL)

As políticas de segurança em nível de linha do PostgreSQL restringem quais usuários podem modificar ou acessar quais linhas da tabela. A segurança em nível de linha pode ser especialmente útil em um cluster multilocatário. Ele permite que locatários individuais tenham acesso SQL completo ao banco de dados enquanto ocultam as informações de cada locatário de outros locatários.

Implementação para aplicativos multilocatários

Podemos implementar a separação de dados do locatário usando uma convenção de nomenclatura para funções de banco de dados que se vincula às políticas de segurança no nível de linha da tabela. Atribuiremos a cada locatário uma função de banco de dados em uma sequência numerada: tenant1, tenant2, etc. Os locatários se conectarão ao Azure Cosmos DB para PostgreSQL usando essas funções separadas. As políticas de segurança em nível de linha podem comparar o nome da função com os valores na coluna de tenant_id distribuição para decidir se permitem o acesso.

Veja como aplicar a abordagem em uma tabela de eventos simplificada distribuída pela tenant_id. Primeiro , crie as funções tenant1 e tenant2. Em seguida, execute os seguintes comandos SQL como o citus usuário administrador:

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á, qualquer pessoa com permissões de seleção para esta tabela pode ver ambas as linhas. Os usuários de qualquer locatário podem ver e atualizar a linha do outro locatário. Podemos resolver o vazamento de dados com políticas de segurança de tabela em nível de linha.

Cada política consiste em duas cláusulas: USANDO e COM CHEQUE. Quando um usuário tenta ler ou gravar linhas, o banco de dados avalia cada linha em relação a essas cláusulas. O PostgreSQL verifica as linhas da tabela existentes em relação à expressão especificada na cláusula USING e as linhas que seriam criadas via INSERT ou UPDATE em relação à 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;

Agora funções tenant1 e tenant2 obter resultados diferentes para suas consultas:

Ligado como inquilino1:

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

Ligado como inquilino2:

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"
*/

Próximos passos