Segurança no nível de linha no Azure Cosmos DB for PostgreSQL
APLICA-SE AO: Azure Cosmos DB for PostgreSQL (da plataforma da extensão de dados Citus para PostgreSQL)
As políticas de segurança no nível de linha do PostgreSQL restringem quais usuários podem modificar ou acessar quais linhas da tabela. A segurança no nível de linha pode ser especialmente útil em um cluster multilocatário. Ela permite que locatários individuais tenham acesso SQL completo ao banco de dados e, ao mesmo tempo, ocultam as informações de cada locatário para outros locatários.
Implementação para aplicativos multilocatários
Podemos implementar a separação de dados de locatário, usando uma convenção de nomenclatura para funções do banco de dados vinculadas às políticas de segurança no nível de linha da tabela. Atribuiremos a cada locatário uma função do banco de dados em uma sequência numerada: tenant1
, tenant2
etc. Os locatários serão conectados ao Azure Cosmos DB for PostgreSQL usando essas funções separadas. As políticas de segurança no nível de linha podem comparar o nome da função com os valores tenant_id
na coluna de distribuição, para decidir se permitem o acesso.
Veja como aplicar a abordagem em uma tabela de eventos simplificada distribuída por tenant_id
. Primeiro, crie as funções tenant1
e tenant2
. Em seguida, execute os seguintes comandos SQL como o usuário 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;
Tal como está, qualquer pessoa com as permissões selecionadas para essa tabela pode ver ambas as linhas. Usuários de qualquer um dos locatários podem ver e atualizar a linha do outro locatário. Podemos resolver o vazamento de dados com políticas de segurança de tabela no nível de linha.
Cada política consiste em duas cláusulas: USING e WITH CHECK. 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 existentes da tabela em relação à expressão especificada na cláusula USING e as linhas que seriam criadas com o INSERT ou UPDATE na 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, as funções tenant1
e tenant2
recebem resultados diferentes para as 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"
*/
Próximas etapas
- Saiba como criar funções em um cluster.
- Confira os conceitos de segurança no Azure Cosmos DB for PostgreSQL