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 praINSERTeUPDATE.
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_idbate 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
USINGeWITH CHECK. Por exemplo, se não checar ouser_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.
GO TO FULL VERSION