Chave de API exposta no GitHub: como revogar e prevenir

Se uma chave de API foi para o GitHub, considere-a comprometida: revogue e gere outra imediatamente. Apagar o commit depois ajuda pouco, porque a chave já pode ter sido copiada.

Atualizado em 5 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Revogar a chave exposta e conferir se alguém a usou
  • Remover o segredo do repositório e do histórico do Git
  • Evitar novos vazamentos com .gitignore, variáveis de ambiente e push protection
Nesta página

Você abriu o e-mail do GitHub ou o painel do provedor e viu o aviso: uma chave de API sua está num repositório público. Ou percebeu sozinho, depois do git push. O primeiro impulso é apagar o arquivo e subir de novo. Não faça só isso.

Robôs varrem repositórios públicos atrás de chaves, então cada minuto conta. A ordem também importa: primeiro você tira o poder da chave, depois limpa o resto.

vazamentosua respostaCommitcom a chaveno código1Varreduraum robôcopia o valor2Revogare geraruma nova3Nova chaveem variávelde ambiente4Apagar o commita cópia já foi feitaLimpar o históricodepois, como higiene
Revogar é o que fecha a porta: a cópia já foi feita, então limpar o histórico vem depois, como higiene.

O que fazer primeiro quando uma chave vaza?#

Trate a chave como comprometida a partir do momento em que foi publicada. Em ordem:

  1. Revogue ou troque a chave no painel do serviço que a emitiu (Stripe, OpenAI, AWS, Discord, o que for). Gere uma nova.
  2. Atualize onde a chave é usada: sua aplicação, a CI e tudo o que dependa dela. Coloque a nova como variável de ambiente, não no código.
  3. Confira o uso: veja no painel do provedor requisições, cobranças ou recursos criados que você não reconhece.
  4. Só então limpe o repositório.

A documentação do GitHub segue a mesma lógica: se o dado vazado é uma credencial, revogá-la ou trocá-la pode bastar, e reescrever o histórico nem sempre é necessário.

Por que apagar o commit não adianta?#

O Git guarda todo o histórico. Um commit novo que remove a chave deixa o commit antigo intacto, e qualquer pessoa consegue ver o conteúdo dele. Mesmo reescrevendo o histórico, existem cópias fora do seu controle:

  • Forks e clones de quem copiou o repositório.
  • Pull requests, cujas referências ficam no GitHub.
  • Visualizações em cache na interface do GitHub.
  • Programas de varredura que já leram o repositório.

Por isso a revogação é a única correção que fecha a porta de verdade. Limpar o histórico é higiene, não segurança.

O GitHub detecta chaves expostas sozinho?#

Em parte. Em repositórios públicos, o secret scanning roda automaticamente, é gratuito e varre todo o histórico em todos os branches. Para chaves de provedores parceiros, o GitHub avisa o provedor, que pode revogar a credencial por conta própria. É por isso que às vezes você recebe um e-mail do provedor dizendo que a chave foi desativada.

A detecção tem limite: ela reconhece padrões de provedores conhecidos, e uma chave de uma API pequena ou uma senha de banco numa string de conexão pode passar batida.

A proteção no push (push protection) bloqueia o git push quando encontra um segredo conhecido. Para contas de usuário ela vem ativa por padrão e impede o envio de segredos a repositórios públicos no GitHub.com. Em repositórios ela vem desativada por padrão e precisa ser habilitada por um administrador. Quem tem permissão de escrita pode ignorar o bloqueio informando um motivo, então ela é uma rede de segurança, não uma garantia.

Como remover a chave do histórico do Git?#

Faça isso depois de revogar. Se o arquivo inteiro era sensível (um .env que foi commitado, por exemplo), o GitHub documenta o uso do git-filter-repo, versão 2.47 ou mais nova:

bash
git clone https://github.com/SEU-USUARIO/SEU-REPOSITORIO && cd SEU-REPOSITORIO
git-filter-repo --sensitive-data-removal --invert-paths --path .env

Para trocar apenas o texto do segredo em todos os arquivos, crie um arquivo com os valores a substituir e use:

bash
git-filter-repo --sensitive-data-removal --replace-text ../segredos.txt

Confira o resultado antes de enviar. Depois, force o envio de todas as referências:

bash
git push --force --mirror origin

O envio das referências refs/pull/* falha porque o GitHub as marca como somente leitura, e isso é esperado. Se outros branches falharem, uma proteção de branch pode estar ativa: desative-a temporariamente e tente de novo.

Antes de reescrever, saiba o que muda:

  • Todos os commits afetados e os seguintes ganham novos hashes, o que pode quebrar ferramentas que dependem deles.
  • Assinaturas de commits e tags são removidas.
  • Pull requests abertos podem perder comentários. Feche ou faça merge antes.
  • Colaboradores precisam clonar de novo. Quem faz git pull e depois git push de um clone antigo pode trazer o segredo de volta.
  • Forks mantêm os dados, e o GitHub não consegue avisar os donos deles.

Só o suporte do GitHub remove visualizações em cache e referências de pull requests, e ele atende esse pedido quando trocar as credenciais não reduz o risco. Se a chave já foi revogada, geralmente não vale o esforço.

Como evitar que aconteça de novo?#

Quatro hábitos cobrem quase todos os casos.

1. Chave fora do código. Leia segredos de variáveis de ambiente. Nas versões recentes do Node.js, você pode carregar um .env com a flag --env-file:

js
// index.js
const apiKey = process.env.API_KEY;
if (!apiKey) throw new Error("API_KEY não definida");
bash
node --env-file=.env index.js

Veja mais em o que são variáveis de ambiente e no checklist de segurança do deploy.

2. .gitignore antes do primeiro commit. Inclua o arquivo de segredos:

gitignore
.env
.env.*
!.env.example

O .gitignore não afeta arquivos que o Git já rastreia. Se o .env já foi commitado, pare de rastreá-lo:

bash
git rm --cached .env
echo ".env" >> .gitignore

Isso tira o arquivo dos próximos commits, mas não do histórico antigo. Você ainda precisa trocar a chave.

3. Um .env.example sem valores reais. Ele documenta quais variáveis o projeto precisa, sem expor nenhuma:

bash
API_KEY=
DATABASE_URL=

Saiba como o arquivo funciona em o que é um arquivo .env.

4. Proteção no push e revisão antes do commit. Mantenha a proteção do GitHub ligada e use git diff --staged antes de commitar. Ferramentas como o gitleaks, rodando como hook de pre-commit ou na CI, também procuram segredos no código.

Se o vazamento foi de um token de bot, o caminho é parecido, com alguns detalhes próprios: veja o que fazer quando o token do bot vaza.

Como fazer isso na Square Cloud#

Na Square Cloud, o passo 2 da primeira seção (atualizar onde a chave é usada) não passa pelo repositório. Cada aplicação tem as próprias variáveis de ambiente, que você define no painel, pela API, pela extensão do VS Code ou pela CLI, com o comando app env set seguido de app restart. A mudança vale no próximo restart, sem rebuild, e uma aplicação não lê as variáveis de outra, mesmo na mesma conta.

Para o hábito 1 virar regra, o painel importa o seu .env local e exporta as variáveis no formato KEY=VALUE, então o arquivo chega à aplicação sem nunca entrar num commit. Se o deploy sai do GitHub, a GitHub Action oficial só precisa de uma API key da plataforma guardada como secret do repositório, na entrada token; em outra CI, a CLI lê a mesma chave da variável SQUARECLOUD_API_KEY, sem login. Nos dois casos, nenhuma credencial fica no código.

Depois de trocar a chave, acompanhe os logs em tempo real da aplicação para confirmar que ela voltou funcionando com o valor novo. Veja como funcionam as variáveis de ambiente e a GitHub Action.

Infraestrutura

Mitigação de DDoS L3/L4/L7 e WAF em todos os planos

Saiba mais

Perguntas frequentes

Apagar o arquivo ou o commit resolve o vazamento?

Não. O segredo continua no histórico do Git, em forks e em clones, e programas automáticos varrem repositórios públicos atrás de chaves. A única correção segura é revogar a chave e criar outra.

Preciso reescrever o histórico depois de revogar a chave?

Na maioria dos casos não. Com a chave revogada, o valor antigo não dá mais acesso a nada, e a documentação do GitHub diz que revogar ou trocar a credencial pode bastar. Reescreva o histórico se o repositório tiver outros dados sensíveis, como dados pessoais.

O GitHub avisa quando eu subo uma chave?

Em repositórios públicos, o secret scanning roda automaticamente e, para chaves de provedores parceiros, o GitHub avisa o provedor, que pode revogá-las. A proteção no push para contas de usuário vem ativa por padrão e bloqueia o envio de segredos conhecidos a repositórios públicos, mas não reconhece todo tipo de chave.

Repositório privado também é risco?

É menos exposto, mas ainda é risco: qualquer pessoa com acesso ao repositório vê a chave, e um repositório privado pode virar público por engano. O mais seguro é nunca guardar segredos no código.

Próximo artigoVazou o token do bot? O que fazer agoraSe o token do bot vazou, redefina-o no Portal do Discord (ou com /token no BotFather) antes de qualquer outra coisa. Veja a ordem certa e como checar o estrago.

Mais em Segurança

Ver todos os 10 artigos