---
id: test-as-user
agent: data-engineer
title: Emular usuário para validar RLS
inputs: [user_id, table, story]
outputs: [resultado positivo/negativo, veredito de cobertura RLS]
elicit: false
modes: [interactive, yolo]
---

# Emular usuário para validar RLS

**Objetivo:** comprovar que uma política RLS faz o que diz — assumindo a identidade de um usuário e
verificando que ele vê/altera só o que é dele (positivo) e é bloqueado no que não é (negativo).

**Pré-condições:**
- RLS está habilitada na tabela e há ao menos uma política instalada (via `db-policy-apply`). Sem
  política, este teste não tem o que validar.
- Existem dados de teste de pelo menos dois donos distintos (o `user_id` alvo e um terceiro). Se não
  houver, semeio com `*seed` antes — sem comparar donos não existe teste negativo.

## Passos

1. **Defina o cenário:** o `user_id` alvo, as linhas que ele DEVE ver e as linhas de um terceiro que
   ele NÃO pode ver/alterar. O cenário rastreia à regra de acesso da story.
2. **Assuma a identidade** numa transação, sem service role (service role bypassa RLS e invalida o
   teste): `BEGIN; SET LOCAL ROLE authenticated; SET LOCAL request.jwt.claim.sub = '{user_id}';`.
3. **Teste positivo (SELECT):** o usuário lê suas linhas. Conta esperada confere? Se não, política
   restritiva demais.
4. **Teste positivo (escrita):** o usuário faz INSERT/UPDATE/DELETE no que é dele e a operação passa.
5. **Teste negativo (SELECT):** consulta as linhas do terceiro — resultado DEVE ser vazio.
6. **Teste negativo (escrita):** tenta UPDATE/DELETE na linha do terceiro — DEVE afetar 0 linhas ou
   ser negado. Linha de outro dono alterada = vazamento.
7. **`ROLLBACK`** sempre ao final: este é um teste, não pode deixar rastro nem mutação no banco.
8. **Emita o veredito:** PASS (positivos passam, negativos bloqueiam) ou FAIL (com a brecha exata).

## Critério de pronto (DoD)

- [ ] Identidade assumida sem service role (RLS realmente em vigor no teste)
- [ ] Positivos passam: o dono lê e escreve o que é dele
- [ ] Negativos bloqueiam: terceiro não lê nem altera o que não é dele (0 linhas)
- [ ] Transação revertida ao final (sem efeito colateral no banco)
- [ ] Veredito registrado no rastro da story

## Falha / recuperação

- **Teste negativo falha (vazamento)** → FAIL; devolvo à `db-policy-apply` com o predicado a corrigir.
  Não declaro a política pronta.
- **`auth.uid()`/claim NULL** → o ambiente não tem auth ou o claim não foi setado; corrijo o `SET
  LOCAL` ou sinalizo a falta de auth e suspendo o teste.
- **Faltam dados de dois donos** → semeio com `*seed` e repito; comparar um dono só não comprova RLS.
- **Esqueci o `ROLLBACK` e mutei o banco** → restauro via `*rollback` do snapshot mais recente.
