5 minutos. Foi só isso que levou.
Um pesquisador de segurança publica uma access key da AWS em um repositório público do GitHub. Faz isso de propósito, como experimento.
Cinco minutos depois, alguém já estava usando para minerar criptomoedas.
Cinco. Minutos.
Existem bots escaneando o GitHub 24/7 procurando exatamente isso: credenciais expostas. E são rápidos. Muito mais rápidos que você se dando conta de que fez merda.
Os números assustam
Segundo o GitHub, em 2024 vazaram 39 milhões de segredos em repositórios públicos. 67% a mais que no ano anterior.
GitGuardian, que se dedica a escanear exatamente isso, encontrou 23,7 milhões de segredos novos só em repos públicos. E o pior: 70% dos segredos detectados em 2022 ainda estavam ativos em 2024.
Dois anos depois. Ainda funcionando. Esperando alguém usar.
Não é só gente aleatória
Toyota teve credenciais da AWS expostas no GitHub que davam acesso ao seu sistema de telemática de veículos. Pearson perdeu dados porque alguém deixou um token do GitLab em um arquivo de configuração. Otelier, uma empresa de hospedagem, viu como exfiltraram 8TB de dados do S3 por credenciais expostas no Bitbucket.
Isso não acontece só com o estagiário. Acontece com empresas do Fortune 500.
O clássico: “É só meu projeto pessoal”
Pois é, claro.
O problema é que esse projeto pessoal tem a mesma API key do OpenAI que você usa em produção. Ou o token do seu bot do Telegram. Ou as credenciais do seu banco de dados de staging que, oh surpresa, tem dados reais porque “assim é mais fácil testar”.
E um dia você faz git push sem pensar. Ou muda o repo de privado para público porque quer mostrar para alguém. Ou o GitHub tem um bug e expõe repos privados temporariamente (já aconteceu).
E então você descobre que sua conta da AWS passou de R$ 100 para R$ 10.000. Em uma noite.
“Mas eu deletei imediatamente”
Outro clássico.
Git é um sistema de controle de versões. Seu trabalho literal é lembrar tudo que aconteceu. Deletar o commit não deleta o segredo do histórico. Fazer force push não deleta dos forks. E definitivamente não deleta dos bots que já copiaram.
Uma vez que um segredo toca um repo público, está comprometido. Ponto. Tem que ser rotacionado.
A pirâmide do desastre
É assim que costuma evoluir a gestão de segredos em um projeto típico:
Nível 1: O inferno
| |
Diretamente no código. Commitado. Em produção. Não ria, isso existe.
Nível 2: O purgatório
| |
Melhor, mas esse .env acaba em um backup, em um zip que você manda pelo Slack, em um HD que você vende no OLX…
Nível 3: O limbo
| |
Ok, mas onde você guarda? Em um post-it? Em um arquivo secrets.txt na área de trabalho? Em uma mensagem do Slack para si mesmo?
A solução: segredos fora do código, fora do disco
Depois de ver como quase me ferrei algumas vezes, decidi centralizar tudo no 1Password e usar sua CLI para injetar segredos quando necessário.
O conceito é simples:
- Os segredos vivem no 1Password, não no meu disco
- O código tem referências aos segredos, não os segredos em si
- Os segredos são injetados em tempo de execução
O padrão .env.template + op inject
Em cada projeto, em vez de um .env com valores reais, tenho um .env.template com referências:
| |
Quando preciso do .env real, executo:
| |
O 1Password lê as referências op://, as resolve com os valores reais, e gera o arquivo. O .env.local está no .gitignore, nunca toca o git.
O que ganho com isso?
1. Um só lugar para todos os segredos
Antes tinha credenciais espalhadas em arquivos .env de 15 projetos, variáveis de ambiente no .bashrc, tokens em mensagens do Slack, e alguns em post-it (não me julguem).
Agora tudo está em um vault do 1Password. Um lugar. Criptografado. Com histórico de mudanças.
2. Rotação de segredos trivial
Antes: mudar uma API key significava procurar em todos os projetos, atualizar arquivos, rezar para não esquecer nenhum.
Agora: atualizo o valor no 1Password, executo op inject em cada projeto, pronto.
3. O código documenta o que precisa
O .env.template é documentação viva. Qualquer pessoa que clone o projeto sabe exatamente quais segredos precisa. Só tem que tê-los no seu próprio 1Password (ou pedir para você).
4. Impossível commitar segredos por acidente
O arquivo que vai para o git só tem referências op://. Mesmo que você faça git add . sem pensar, não está expondo nada.
5. Sincronização entre máquinas grátis
Mac novo? Instala 1Password, faz login, op inject. Todos seus segredos disponíveis sem copiar arquivos nem mandar nada pelo Slack.
Para o dia a dia: lazy loading no Fish
Para comandos que precisam de credenciais (como oco para commits com IA), tenho isso no meu config do Fish:
| |
A primeira vez que executo oco, me pede Touch ID. A partir daí, a variável está carregada na sessão.
O único inconveniente
Sim, há um: você tem que autorizar com Touch ID ou senha de vez em quando.
Otimizei configurando o 1Password para lembrar autorizações por 24 horas e só bloquear ao adormecer o Mac. Mas sim, de vez em quando você tem que colocar o dedo.
É um pequeno preço a pagar por não aparecer nas estatísticas do GitGuardian.
Não é opcional
Olha, entendo que tudo isso soa como paranoia. “Comigo não vai acontecer”. “É só um projeto pequeno”. “Não tenho nada importante”.
Mas pense nisso: você tem alguma API key paga? OpenAI? AWS? Qualquer serviço que cobre por uso?
Então você tem algo que alguém pode explorar.
E os bots não descansam. Não distinguem entre o projeto de uma startup e a lição de casa de programação de um estudante. Escaneia tudo, testa tudo, explora tudo.
39 milhões de segredos vazados em 2024. 70% dos de 2022 ainda ativos.
A gestão correta de segredos não é uma best practice. É higiene básica.
Como lavar as mãos. Você não faz porque é divertido. Você faz porque a alternativa é pegar uma infecção.
Seus segredos no git são uma infecção esperando para acontecer.
Resumo executável:
- Instale o 1Password e sua CLI (
brew install 1password-cli) - Crie um vault para desenvolvimento
- Migre seus segredos de arquivos
.envpara o vault - Crie
.env.templatecom referênciasop:// - Adicione
.env.localao.gitignore - Regenere com
op injectquando necessário
E pronto. Trinta minutos de setup que te poupam de aparecer no próximo relatório do GitGuardian.
Suas credenciais da AWS vão agradecer.
Atualização: Depois de implementar tudo isso, descobri que o 1Password me pedia Touch ID demais. Tanto que comecei a aprovar sem olhar. Isso tem um nome em segurança e não é bom. Leia Quando a segurança te pede permissão tantas vezes que você para de ler para ver como resolvemos.