CodeGym /Cursos /SQL SELF /Controle de acesso por linha: Row-Level Security (RLS)

Controle de acesso por linha: Row-Level Security (RLS)

SQL SELF
Nível 47, Lição 3
Disponível

Se permissões no nível de roles e tabelas são tipo "o segurança na porta de entrada", então Row-Level Security é o segurança particular que checa se cada usuário pode entrar em cada sala do prédio.

O RLS faz com que o usuário só consiga mexer nas linhas da tabela que ele realmente pode acessar. Por exemplo:

  • No e-commerce, o gerente só pode ver os próprios pedidos.
  • No CRM, o funcionário só vê os clientes do próprio time.
  • No sistema bancário, o cliente só pode acessar as próprias contas.

Como funciona o RLS

O RLS funciona com base em políticas de acesso. As políticas definem quais linhas da tabela são visíveis pra uma role ou usuário e quais podem ser alteradas (INSERT, UPDATE, DELETE).

Por padrão, o RLS vem desativado pra todas as tabelas, e você precisa ativar manualmente.

Ativando o RLS pra uma tabela

Bora criar uma tabela orders, onde ficam os pedidos do e-commerce:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    product_name TEXT NOT NULL,
    price NUMERIC NOT NULL
);

Vamos colocar alguns dados de teste:

INSERT INTO orders (user_id, product_name, price)
VALUES
    (1, 'Smartphone', 500),
    (2, 'Notebook', 1000),
    (1, 'Fone de ouvido', 100),
    (3, 'Teclado', 50);

Agora vamos ativar o RLS nessa tabela:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

O que rolou aqui? A gente ativou o mecanismo do RLS, mas ainda não criou nenhuma política. Enquanto não tiver política criada, o RLS não muda nada no acesso à tabela.

Criando uma política de acesso

Pra adicionar regras de controle de acesso, usa esse comando:

CREATE POLICY nome_da_politica
ON tabela
[FOR { SELECT | INSERT | UPDATE | DELETE }]
TO role
USING (condicao_de_acesso)
WITH CHECK (condicao_de_verificacao);
  • FOR: define pra quais operações a política vale (SELECT, INSERT, UPDATE, DELETE). Se não colocar, vale pra tudo.
  • TO: diz pra quais roles a política é ativa. Se não colocar, vale pra qualquer role.
  • USING: define a condição pra linha ser visível pro usuário.
  • WITH CHECK: define a condição de verificação pra INSERT e UPDATE.

Exemplo: acesso só aos próprios pedidos

Vamos criar uma política que deixa o usuário ver só os próprios pedidos. O id do usuário atual tem que bater com o user_id da tabela:

CREATE POLICY user_can_view_own_orders
ON orders
FOR SELECT
USING (user_id = current_user::INT);

O que tá rolando aqui?

  • A política chama user_can_view_own_orders.
  • Ela vale pra operação SELECT.
  • Só as linhas onde user_id bate com o id do usuário atual (current_user) ficam visíveis.

Então, se você logar como usuário com user_id = 1, só vai ver seus próprios pedidos.

Testando o RLS

Vamos criar dois usuários: user1 e user2.

CREATE ROLE user1 LOGIN PASSWORD 'password1';
CREATE ROLE user2 LOGIN PASSWORD 'password2';

Vamos dar acesso à tabela pra essas roles:

GRANT SELECT ON orders TO user1, user2;

Agora troca pro usuário user1 e faz a consulta:

SELECT * FROM orders;

Resultado: você só vai ver as linhas onde user_id = 1.

Políticas pra INSERT

Digamos que a gente quer deixar o usuário adicionar só os próprios pedidos (ou seja, a linha com user_id tem que bater com o id do usuário atual).

Vamos criar uma política pra INSERT:

CREATE POLICY user_can_insert_own_orders
ON orders
FOR INSERT
WITH CHECK (user_id = current_user::INT);

Agora, se o user1 tentar adicionar um pedido com user_id diferente de 1, vai dar erro.

Políticas pra UPDATE e DELETE

Dá pra criar políticas pra alterar e deletar dados do mesmo jeito. Por exemplo:

Pra atualizar só os próprios dados:

CREATE POLICY user_can_update_own_orders
ON orders
FOR UPDATE
USING (user_id = current_user::INT)
WITH CHECK (user_id = current_user::INT);

Pra deletar só os próprios dados:

CREATE POLICY user_can_delete_own_orders
ON orders
FOR DELETE
USING (user_id = current_user::INT);

Usando várias políticas

Você pode criar várias políticas pra uma tabela só. Todas vão ser aplicadas ao mesmo tempo. Por exemplo, se uma role tiver várias regras, o PostgreSQL vai checar todas (lógico AND).

Checando e debugando o RLS

Pra ver quais políticas estão criadas pra uma tabela, usa o comando:

\di+ nome_da_tabela

Se quiser desativar o RLS temporariamente (tipo pra admin), faz assim:

ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

A role de admin SUPERUSER por padrão não é limitada pelo RLS, então vê tudo.

Erros comuns ao configurar o RLS

Os erros mais comuns são esquecer de:

  • Ativar o RLS com ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
  • Criar políticas pra todas as operações (SELECT, INSERT, UPDATE, DELETE).
  • Colocar a condição certa no USING e WITH CHECK. Por exemplo, se não checar o user_id, pode acabar liberando tudo pra geral.

Row-Level Security é uma das ferramentas mais poderosas de segurança no PostgreSQL. Dá pra controlar o acesso linha por linha e automatizar o gerenciamento de permissões, o que é essencial pra apps complexos que precisam proteger bem os dados.

2
Tarefa
SQL SELF, nível 47, lição 3
Bloqueado
Políticas complexas: acesso de leitura e edição
Políticas complexas: acesso de leitura e edição
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION