Uma aplicação de produção começou a devolver erros de autenticação para usuários reais.
O primeiro impulso foi procurar uma queda de servidor, um processo travado ou algum problema no banco.
Nada disso tinha acontecido.
Os servidores estavam ativos. Os processos estavam rodando. O container continuava respondendo ao health check.
Mesmo assim, a operação estava parcialmente parada.
O teste que parecia inofensivo
Durante uma atividade normal de desenvolvimento, foi gerado um novo login contra um ERP externo.
A integração usava tokens de sessão fornecidos por esse ERP. A aplicação mantinha esses tokens em cache para não precisar autenticar a cada chamada.
O detalhe perigoso era que desenvolvimento e produção usavam a mesma credencial externa.
O fornecedor não tratava cada ambiente como uma identidade isolada. Um novo login podia invalidar ou deslocar uma sessão que a produção ainda estava usando.
Poucos minutos depois, a aplicação começou a receber respostas equivalentes a “login ou senha inválido” em várias operações do ERP.
O erro aparecia em massa, para usuários diferentes. Isso era um sinal importante: não era um registro específico nem um problema isolado de usuário. Era a autenticação da aplicação contra a dependência externa.
O servidor estava saudável
Esse tipo de incidente é perigoso porque os indicadores tradicionais continuam verdes.
O processo não caiu. O container não reiniciou. O endpoint de health check respondeu. O banco continuou disponível.
Mas a função principal da integração estava quebrada.
Em uma ocorrência, usuários perceberam o problema rapidamente e abriram chamados. Em outra, o erro ficou silencioso por dias. Os jobs continuavam executando, mas uma etapa importante retornava zero registros. Como não havia um alerta para esse resultado de negócio, a infraestrutura continuava reportando saúde.
Essa diferença merece uma definição explícita:
Saúde técnica significa que o sistema está executando.
Saúde operacional significa que ele está entregando o resultado esperado.
Uma não garante a outra.
A cadeia causal
O incidente não tinha uma única causa isolada. Ele era uma cadeia de decisões razoáveis que, combinadas, criaram um risco grande:
- Ambientes diferentes compartilhavam uma credencial externa.
- O fornecedor tinha regras de sessão concorrente que não estavam sob nosso controle.
- A aplicação reutilizava um token em cache e não tinha recuperação automática confiável.
- O token existia em mais de um lugar, como arquivo de ambiente, CI e Secret Manager.
- O deploy podia recriar configurações antigas.
- O health check verificava o processo, não a integração crítica.
- Os jobs não tinham alerta específico para volume de resultado inesperadamente zerado.
O primeiro incidente sugeriu que o fornecedor permitia apenas uma sessão por credencial. Testes posteriores indicaram uma hipótese mais cuidadosa: poderia existir um limite ou pool pequeno de sessões, com invalidação dos tokens mais antigos quando novas sessões eram criadas.
O tamanho exato desse limite não foi provado. Para a operação, porém, o efeito era o mesmo: gerar sessões novas contra uma credencial compartilhada podia derrubar uma sessão ainda usada pela produção.
Essa distinção é importante. Uma boa análise não transforma uma hipótese conveniente em fato só porque ela explica o primeiro sintoma.
O conserto emergencial
A recuperação imediata foi operacional:
- Gerar tokens novos usando credenciais de autenticação mais estáveis.
- Validar esses tokens contra endpoints reais antes de aplicá-los.
- Atualizar as configurações do ambiente legado, do CI e do ambiente em nuvem.
- Reiniciar os processos para que carregassem os valores novos.
- Observar chamadas bem-sucedidas durante um período de estabilização.
Isso restaurou o serviço, mas ainda era um band-aid. Trocar o valor de um segredo não remove o risco de ele ser revogado novamente.
Também havia um problema de distribuição. Atualizar apenas o .env do servidor não bastava se o próximo deploy recriasse o arquivo a partir de um parâmetro antigo do CI.
A correção estrutural
O desenho da correção precisava eliminar a dependência de intervenção manual:
1. Separar ambientes de verdade
Desenvolvimento, homologação e produção precisam de credenciais externas diferentes sempre que o fornecedor permitir.
Quando isso não for possível, a restrição deve ser tratada como um risco formal, com procedimento de diagnóstico e controles explícitos.
2. Reautenticar automaticamente
A aplicação não deve depender indefinidamente de um token de sessão salvo no ambiente. Quando o token expira ou é rejeitado, o sistema precisa obter outro de maneira controlada.
3. Compartilhar o cache entre processos
Um cache em memória cria uma sessão diferente para cada processo. Com vários workers, cron e containers, a própria aplicação pode gerar sessões demais.
Um cache compartilhado reduz esse comportamento e torna o estado da autenticação visível para todos os processos.
4. Coordenar a reautenticação
Se vários processos perceberem o token inválido ao mesmo tempo, todos podem tentar fazer login. Isso cria uma nova rajada de sessões justamente no momento em que o sistema está se recuperando.
Um lock distribuído permite que apenas um processo faça a reautenticação. Os demais aguardam o novo token aparecer no cache compartilhado.
5. Monitorar o resultado do negócio
O health check precisa responder perguntas além de “o processo está vivo?”
- A autenticação com o ERP está funcionando?
- A última importação trouxe registros dentro do esperado?
- A fila recebeu itens quando deveria?
- A taxa de erro da dependência externa mudou abruptamente?
Nem toda checagem precisa ser uma chamada pesada em produção. Métricas de resultado, idade do último sucesso e alertas de volume anormal já capturam uma classe importante de falhas silenciosas.
O que esse incidente ensinou
O erro mais fácil de apontar seria o login manual. Ele foi o gatilho de uma ocorrência, mas não explica sozinho por que a produção era vulnerável.
O risco real estava na combinação de:
- credencial compartilhada;
- sessão externa com regras pouco conhecidas;
- token sem renovação automática;
- configuração replicada em vários lugares;
- monitoramento sem visão do resultado operacional.
Esse padrão aparece em muitos contextos. Pode ser um ERP, uma API bancária, um gateway de pagamentos ou qualquer fornecedor que use sessões, tokens e limites próprios.
Quando uma integração é crítica, disponibilidade não pode ser medida apenas pelo estado do servidor.
Checklist para evitar o mesmo problema
- Use credenciais distintas por ambiente.
- Nunca gere login de desenvolvimento contra uma credencial de produção.
- Documente se o fornecedor limita sessões ou invalida tokens antigos.
- Tenha refresh ou reautenticação automática.
- Use cache compartilhado quando houver múltiplos processos.
- Coordene a recuperação com lock distribuído.
- Mantenha uma fonte única para secrets e parâmetros de deploy.
- Alimente alertas com métricas de negócio.
- Teste também o caminho de falha da dependência externa.
- Diferencie health check técnico de health check operacional.
A aplicação estava saudável. O negócio estava parado.
O objetivo da arquitetura e da operação é garantir que essas duas frases nunca mais possam ser verdadeiras ao mesmo tempo.
This article was originally published by DEV Community and written by William Scussel.
Read original article on DEV Community