ADR 0245 — Acesso rápido por papel só no ambiente local
- Status: aceito
- Data: 2026-11-03
- Referencia: os ADRs 0031 e 0032 (a sessão e o cookie), 0073 (o vocabulário
dev/prd), 0119 (as imagens publicadas) e 0155 (RN-546). Nenhum deles é editado.
Contexto
O dono (AT-722, 03/11) pediu uma caixa de diálogo na tela de login em que escolher um papel já entra, para o desenvolvimento e para o TP-01 na instalação construída nesta máquina. Produção é tudo que sai por GitHub Actions. Uma porta que emite sessão sem credencial é fronteira de autenticação: precisa de barreira que não dependa de lembrar de desligá-la.
Decisão
- Uma variável de ambiente, três valores.
BRABO_AMBIENTEna api eVITE_BRABO_AMBIENTEno web (o Vite só expõeVITE_*):dev(Actions nadev),prd(Actions namaine tags de release) elocal(só fora das Actions). O acesso rápido existe só comlocal; ausente, vazio ou qualquer outro valor, não existe. - Quatro camadas.
- Build:
AMBIENTEnodocker-bake.hcl(default vazio) vira build-argBRABO_AMBIENTE(api) eVITE_BRABO_AMBIENTE(web); no web o ramo morto some do bundle, sem chunk. - Arquivo da imagem: o Dockerfile da api grava
/app/AMBIENTE_DA_IMAGEM(environment:do compose sobrescreveENV, não arquivo). - Runtime: o predicado
acessoRapidoLigadoexige a variávellocalE o arquivo ausente (pnpm dev) oulocal; o módulo só é registrado assim, e fora disso as rotas dão 404.NODE_ENVnão entra: a instalação rodaproduction. - Provas: spec do predicado, spec do módulo,
scripts/ci/ambiente-nas-actions.spec.ts(nenhum workflow ligalocal), passos dodocker/smoke.she teste do E2E.
- Build:
- Produção é tudo que sai por Actions:
ci.ymlpassadevouprdpela base da PR e orelease.ymlpassaprd. Oinstall.shnão muda; o TP-01 liga olocalpelo runbook. - Contas
<papel>@brabo.dev(owner,maintainer,developer,viewer, oROLE_ORDER).POST /auth/dev-login { papel }resolve só essas contas, nunca e-mail livre, e emite a sessão pelo mesmoEmitirSessaoUseCasedo login. Na instalação a rota garante as contas pelo núcleoProvisionarUsuarioUseCasecom senha ALEATÓRIA descartada, num workspace próprio ("acesso rápido (local)"), sem acesso aos projetos reais. A RN-546 fica intacta: não há senha conhecida e o seed segue recusando produção. Sem usuário na instalação, 409 (afirst-accountcria a primeira conta). - Bind em
127.0.0.1. Comlocal, as portas da api e do web da instalação ficam presas a127.0.0.1(BRABO_BIND). dev@brabo.devdo seed passa adeveloper@brabo.dev.
Consequências
- Riscos declarados: com
local, quem alcança a porta entra como qualquer papel (por isso o bind); a rota não tem rate limit nem CSRF, como o/auth/login, e a defesa é ela não existir fora delocal; imagem construída à mão comAMBIENTE=localé local por definição; um banco semeado antes mantém odev@brabo.devórfão até o próximo reset. - A rota não aparece no
route-surface.specnem noopenapi.json; fica na prosa dedocs/security-surface.md.