---
id: create-rls-policies
agent: data-engineer
title: Projetar políticas RLS para o schema
inputs: [schema, modelo de domínio (regras de propriedade do dado)]
outputs: [DDL de políticas RLS, docs/data/RLS.md, casos de teste positivos e negativos]
elicit: false
modes: [interactive, yolo]
---

# Projetar políticas RLS para o schema

**Objetivo:** garantir que cada tabela pública aplique Row Level Security — quem pode ler/escrever
qual linha é decidido pelo banco, não pela confiança no código da aplicação.

**Pré-condições:**
- O schema existe (saída de `create-schema`). Sem tabelas, não há o que proteger.
- As regras de propriedade do dado estão no modelo de domínio (quem é dono de qual linha:
  usuário, tenant, papel). Se faltam, **pare** e volte ao modelo — RLS sem regra de propriedade é chute.
- A camada de auth está definida. Se não há auth, **aviso explicitamente** que `auth.uid()` retorna
  `NULL` e as políticas baseadas em identidade não vão filtrar nada.

## Passos

1. **Habilite RLS em toda tabela pública:** `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` e
   `FORCE ROW LEVEL SECURITY` onde o dono também não deve bypassar. Tabela pública sem RLS é vazamento.
2. **Para cada tabela, derive as políticas das regras de propriedade** do modelo: `SELECT`,
   `INSERT`, `UPDATE`, `DELETE` separadamente. Cada política expressa "qual linha este papel enxerga
   ou altera" — tipicamente via `auth.uid()`, coluna de tenant ou papel.
3. **Escreva `USING` (leitura/escrita do que já existe) e `WITH CHECK` (o que pode ser inserido/
   atualizado) corretamente.** Esquecer `WITH CHECK` deixa o usuário gravar linha que ele nem
   conseguiria ler — buraco clássico.
4. **Decida o modo:** KISS (uma política ampla por tabela) quando o acesso é simples; granular
   (política por operação/papel) quando o domínio exige. Documente a escolha.
5. **Trate o service role com cuidado extremo:** ele bypassa RLS. Liste onde ele é usado e por quê —
   service role sem justificativa é risco.
6. **Escreva os casos de teste — positivos E negativos.** Para cada política: um caso que DEVE passar
   (o dono acessa sua linha) e um que DEVE falhar (outro usuário NÃO acessa). RLS só validada com o
   teste negativo verde; sem ele, eu não declaro a política segura.
7. **Documente em `docs/data/RLS.md`** as políticas, o modo escolhido, o tratamento de service role e
   os casos de teste. A aplicação real (`db-policy-apply`) e a emulação de usuário (`test-as-user`)
   acontecem em tasks dedicadas.

## Critério de pronto (DoD)

- [ ] RLS habilitada em toda tabela pública
- [ ] Política por operação derivada das regras de propriedade do modelo de domínio
- [ ] `USING` e `WITH CHECK` corretos em cada política aplicável
- [ ] Uso de service role listado e justificado
- [ ] Cada política tem caso de teste positivo E negativo definido
- [ ] `docs/data/RLS.md` escrito; aviso emitido se não há camada de auth

## Falha / recuperação

- **Falta regra de propriedade do dado** → volto ao `db-domain-modeling`; não invento quem é dono.
- **Não há auth configurada** → não declaro RLS segura; registro o aviso de `auth.uid()` NULL e
  escalo para o @architect/@devops resolverem a camada de identidade.
- **Política some no teste negativo** (vazamento detectado) → bloqueio o avanço; política que falha o
  teste negativo não vai para produção.
