| name | politica-rls |
| description | Escreve a política de Row Level Security para uma tabela territorializada ou com dado pessoal, garantindo isolamento por microrregião como regra de banco. Use ao criar qualquer tabela com `microrregiao_id` ou com classificação Pessoal/Sensível. |
Procedimento
- Confirmar territorialização: a tabela tem
microrregiao_id? Se não, mas tem dado pessoal de uma pessoa específica, definir a política por ator_id ou usuario_id.
- Habilitar RLS na tabela:
ALTER TABLE <schema>.<tabela> ENABLE ROW LEVEL SECURITY;
- Escrever a política
USING (controla leitura): filtra linhas que a identidade corrente pode ver.
- Escrever a política
WITH CHECK (controla escrita): garante que a identidade só cria/atualiza linhas dentro do seu escopo.
- Testar contra o banco real via conector
postgres-hml: simular um agente de microrregião A consultando dado de microrregião B — deve voltar 0 linhas.
- Cobrir com teste de integração: o teste cria 2 usuários em microrregiões diferentes, registra dado em cada, e confirma que cada um vê apenas o seu.
Modelo territorial padrão
CREATE POLICY <tabela>_select_por_territorio
ON <schema>.<tabela>
FOR SELECT
USING (
microrregiao_id IN (
SELECT microrregiao_id FROM acesso.escopo_territorial
WHERE identidade_id = corrente_identidade()
)
OR corrente_tem_papel('coordenacao_geral')
OR corrente_tem_papel('administracao_sistema')
);
CREATE POLICY <tabela>_insert_no_proprio_territorio
ON <schema>.<tabela>
FOR INSERT
WITH CHECK (
microrregiao_id IN (
SELECT microrregiao_id FROM acesso.escopo_territorial
WHERE identidade_id = corrente_identidade()
)
OR corrente_tem_papel('coordenacao_geral')
OR corrente_tem_papel('administracao_sistema')
);
CREATE POLICY <tabela>_update_no_proprio_territorio
ON <schema>.<tabela>
FOR UPDATE
USING ()
WITH CHECK ();
Modelo pessoal (dado do próprio titular)
CREATE POLICY <tabela>_select_proprio_dado
ON <schema>.<tabela>
FOR SELECT
USING (
titular_uuid = corrente_identidade_uuid()
OR corrente_tem_papel('administracao_sistema')
);
Funções de apoio (criadas em D03 acesso)
| Função | Retorno |
|---|
corrente_identidade() | bigint — id da identidade autenticada |
corrente_identidade_uuid() | uuid — uuid público correspondente |
corrente_tem_papel(text) | boolean — true se a identidade tem o papel |
acesso.escopo_territorial | tabela — mapa identidade → microrregioes |
Antipatterns rejeitados
USING (true) (anula a RLS).
- Política só de
SELECT sem INSERT/UPDATE correspondentes (deixa criar dado fora do escopo).
- Política com
corrente_tem_papel('agente_inovacao') no OR (qualquer agente passa — perde o filtro territorial).
- RLS habilitada mas com
ALTER TABLE ... FORCE ROW LEVEL SECURITY ausente (superuser ignora).
Saída
Política RLS no arquivo de migração da tabela, função auxiliar atualizada se necessário, teste de integração que confirma o isolamento, atualização da seção de segurança no catálogo do domínio.