7. Padrões · versão 2.0.0
Segurança
Regras universais, válidas em toda ADR de todo projeto.
Segredos e credenciais
- Nunca commitar
.env.localou qualquer arquivo com segredos. - Não expor segredos no frontend. Chaves sensíveis só no servidor.
- Não logar tokens, chaves de API, payloads sensíveis ou dados confidenciais.
Dados e ambientes
- Não acessar banco de produção durante o desenvolvimento.
- Não deletar arquivos, pastas, tabelas, colunas, dados ou configurações sem autorização explícita.
- Dados sensíveis reais (clientes, contratos) não entram em
resources/versionado sem cuidado — preferir anonimização ou referência.
Aplicação
- Autenticação antes de qualquer operação protegida.
- Validação Zod em toda entrada de API (princípio 7).
- Tipagem total para fechar classes inteiras de erro (princípio 6).
Autorização por escopo (regra crítica)
Estar autenticado não é estar autorizado. Toda rota que retorna ou modifica dados precisa checar, explicitamente, se aquele usuário pode acessar aquele recurso. Autenticação responde “quem é”; autorização responde “tem direito a isso”. A segunda checagem nunca é dispensável, mesmo que a primeira tenha passado.
O risco que esta regra evita
A classe de bug mais comum e mais grave em APIs é o IDOR (Insecure Direct Object Reference):
o endpoint confia que o ID na URL “pertence” a quem está logado. Um usuário comum chama
GET /api/orders/42 e recebe o pedido de outra pessoa. Ou chama GET /api/users e recebe a
lista inteira — endpoint que só admin deveria enxergar. Nada disso é hipotético.
Como aplicar
- Cada rota declara o escopo que exige (papel, dono do recurso, tenant) e checa esse escopo antes de ler/escrever — não depois.
- Filtrar por dono no próprio query do Prisma, não na resposta.
where: { id, userId: session.userId }em vez de buscar peloide conferir ouserIddepois. Filtrar depois é exatamente o caminho que vaza dados em listagens. - Papel/escopo nunca vem do cliente. Vem da sessão no servidor. Header, query string ou
campo do body dizendo
role=adminé entrada do usuário — trate como tal. - Listagens são filtradas no servidor pelo escopo do usuário. Nunca devolva “tudo” e deixe o frontend esconder. O que o cliente não pode ver, o servidor não envia.
- Rotas de admin ficam separadas e checam papel explicitamente (ex.:
/api/admin/...exigindosession.role === 'admin'). Não basta ocultar o link no menu. - Erro padrão é negar. Em dúvida, 403. Se a rota não checou escopo, ela está errada — não importa o quanto a UI “garante” que o usuário nunca chegaria ali.
Exemplo concreto
// errado: confia no ID da URLconst order = await prisma.order.findUnique({ where: { id } });return Response.json(order);
// certo: o escopo do dono entra no whereconst order = await prisma.order.findFirst({ where: { id, userId: session.userId },});if (!order) return new Response(null, { status: 404 });return Response.json(order);A diferença não é estilística — é a fronteira entre “API funcional” e “vazamento de dados de outro usuário”.
Esta checagem é da rota (ver Backend e API). O middleware base autentica; quem autoriza a operação específica sobre o recurso específico é a própria rota, porque só ela conhece o domínio.