Chave vazada no GitHub
O que fazer quando uma chave de API vai parar no GitHub: como a proteção de envio funciona, como resolver um envio bloqueado e a ordem certa se a chave já subiu.
- GitHub
- conferido na documentação oficial
- exemplos com chave falsa
Publicado em
O que aconteceu
Uma chave de API é uma senha que um serviço (de IA, pagamento, e-mail ou nuvem) entrega para o seu programa usar a sua conta. Quem tem a chave age como você naquele serviço.
A chave "vaza" quando vai parar num lugar que outras pessoas conseguem ver. O caso mais comum é escrever a chave no código e enviar o projeto para um repositório público no GitHub sem perceber.
A documentação do GitHub diz que qualquer segredo vazado deve ser considerado comprometido imediatamente, e que scanners automáticos conseguem encontrar segredos expostos publicamente em minutos.
Por isso este guia tem duas partes: o que o GitHub faz para barrar o envio antes de a chave sair do seu computador e o que fazer, na ordem certa, se ela já saiu.
Quatro palavras que aparecem ao longo do guia (explicação geral de Git, fora da documentação do GitHub):
- Repositório: a pasta do projeto guardada no GitHub.
- Commit: um registro salvo do projeto, uma foto dos arquivos naquele momento.
- Push (envio): o comando
git push, que manda os seus commits para o repositório no GitHub. - Histórico: a lista de todos os commits. Cada commit guarda uma versão dos arquivos.
Todas as chaves deste guia são falsas e aparecem como sk-EXEMPLO-.... O que vem da documentação do GitHub aparece sem marcação. O que é recomendação do guia vem marcado como "Recomendação do guia".
A proteção de push do GitHub
A proteção de push (push protection) confere o que você está enviando. Se encontra um segredo, bloqueia o envio e mostra uma mensagem com o motivo.
Para usuários, ela vem ativada por padrão em repositório público. A documentação a descreve como específica da sua conta do GitHub e disponível no GitHub.com.
O que ela faz
- Bloqueia o envio quando encontra um segredo com padrão reconhecido, e mostra uma mensagem com o motivo.
- Vem ativada por padrão para usuários, em repositório público.
- Vale para a sua conta do GitHub.
O que ela não promete
- Pegar qualquer chave ou senha: a documentação descreve o bloqueio para credenciais de provedores com suporte.
- Funcionar em repositório privado: a documentação consultada não diz nada sobre isso.
- Apagar uma chave que já foi enviada: a página descreve o bloqueio no momento do envio.
A mesma página descreve outros tipos de detecção (padrões genéricos, personalizados e detecção por IA), mas não diz que a proteção do usuário cobre todos eles. Os padrões genéricos, por exemplo, precisam estar ativados nas configurações de segurança do repositório.
Onde conferir na sua conta
- No canto superior direito de qualquer página do GitHub, clique na sua foto de perfil e depois em Settings.
- Na seção Security da barra lateral, clique em Code security.
- Em User, ao lado de "Push protection for yourself", confira se a proteção está ativada.
Dica
Recomendação do guia: se o GitHub não bloqueou o envio, não conclua que a chave está segura. A proteção reconhece padrões de provedores com suporte e pode não reconhecer o da sua chave. Mantenha a chave fora do código desde o começo.
Se o envio foi bloqueado
Quando você roda git push e o GitHub encontra um segredo, o envio não é concluído e o terminal mostra uma mensagem com o motivo. Ela lista todos os commits que contêm o segredo. Na página oficial, cada item aparece em locations, com o commit e o path (arquivo e linha) onde o segredo está.
A regra da documentação: para resolver um envio bloqueado, você precisa remover o segredo de todos os commits em que ele aparece. Tirar a chave só do arquivo atual não resolve se ela continua num commit mais antigo da mesma sequência.
Nota
Recomendação do guia: se você também colou a chave em outro lugar (mensagem, print ou outro repositório), trate-a como vazada e vá direto para a seção "Se a chave já subiu: a ordem certa".
Parte A: tire a chave do código
Recomendação do guia: guarde a chave num arquivo .env, que fica só no seu computador, e leia o valor no código por variável de ambiente. A documentação do GitHub recomenda usar variáveis de ambiente em vez de escrever o segredo no código.
API_KEY=sk-EXEMPLO-...const apiKey = 'sk-EXEMPLO-...';const apiKey = process.env.API_KEY;import os
api_key = os.environ["API_KEY"]Muitas ferramentas leem o .env sozinhas. Nas outras, uma biblioteca que carrega arquivos .env resolve. Confira a documentação da sua ferramenta.
Agora impeça o Git de guardar o .env. A página do GitHub sobre arquivos ignorados diz que você pode criar um arquivo .gitignore na raiz do repositório. Crie o arquivo com esta linha:
.envSe o .env já tinha entrado no Git, só o .gitignore não basta. A mesma página diz que, para ignorar um arquivo que já está registrado, você precisa antes tirá-lo do controle do Git:
git rm --cached .envParte B: tire a chave dos commits
Se a chave entrou no último commit da sua branch, atualize esse commit em vez de criar um novo. O comando abaixo atualiza o commit original:
git commit --amend --all
git pushNota
Explicação geral de Git: o git commit --amend abre um editor de texto com a mensagem do commit. Salve e feche o editor para continuar. Se não quiser mudar a mensagem, não altere o texto.
Dica
Recomendação do guia: o --all só inclui arquivos que o Git já acompanha. Se você acabou de criar o .gitignore, rode git add .gitignore antes do git commit --amend --all.
Se a chave entrou num commit anterior, descubra qual é o mais antigo que a contém. A mensagem de erro lista os commits e o git log mostra o histórico da branch, com as datas:
git logCom o identificador (ID) do commit mais antigo que contém a chave, comece um rebase interativo. Explicação geral de Git: o ~1 faz o rebase começar um commit antes dele.
git rebase -i ID-DO-COMMIT~1No editor que abrir, troque pick por edit na primeira linha, a do commit que você identificou. Salve e feche o editor. Depois remova a chave do código e rode:
git add .
git commit --amend
git rebase --continue
git pushNota
Existe um espaço entre add e .. O ponto faz parte do comando.
Atenção
Não existe atalho seguro para um envio bloqueado. O caminho é tirar a chave de todos os commits em que ela aparece.
Se a chave já subiu: a ordem certa
Se a chave chegou ao repositório, apagar o arquivo não resolve. A documentação do GitHub diz que remover o segredo do código, enviar um commit novo ou apagar e recriar o repositório não impede que o segredo seja explorado.
Explicação geral de Git: o histórico guarda cada versão do projeto. Se um commit antigo contém a chave, quem abrir esse commit consegue ver. A documentação diz que o segredo pode continuar no histórico de commits do repositório.
A ordem abaixo segue a do tutorial oficial do GitHub sobre como remediar um segredo vazado:
- Revogue ou troque a chave no serviço que a emitiu.
- Confira se houve uso indevido, no painel do provedor.
- Limpe o histórico com
git-filter-repo, com cuidado.
Nota
O tutorial oficial tem outras etapas, como identificar o segredo, avaliar o risco e fechar o alerta. Este guia cobre três delas: revogar, conferir e limpar.
Passo 1: revogue ou troque a chave no serviço que a emitiu
Revogar é invalidar a chave, para que ela pare de funcionar. Trocar (rotacionar) é gerar uma chave nova no lugar dela. Segundo a documentação, revogar o segredo no provedor dele é o passo de remediação mais importante, e remover o segredo do código não é suficiente.
A página sobre remoção de dados sensíveis diz que, depois que o segredo é revogado ou trocado, ele não pode mais ser usado para acesso.
Faça isso no painel do serviço que emitiu a chave. Os nomes dos menus mudam de serviço para serviço. Procure a área de chaves de API, tokens ou credenciais e siga a instrução de revogação do próprio provedor. Se você não tem acesso ao painel, peça a quem é dono da chave ou administra o repositório.
Avise também o dono da chave e quem administra o repositório, como a documentação recomenda.
Se a chave está em uso em produção
Revogar de uma vez pode derrubar a aplicação. Quando a queda é uma preocupação, a documentação sugere esta ordem: gerar a nova chave primeiro, com as mesmas permissões, fazer a aplicação usar a nova e só então revogar a antiga.
- Gere a chave nova no provedor, com as mesmas permissões da antiga.
- Atualize a aplicação e os outros serviços que usavam a antiga e confirme que eles usam a nova.
- Revogue a chave antiga.
Atenção
Não deixe a chave antiga ativa além do necessário. A mesma página manda priorizar a revogação imediata do segredo.
E se o próprio GitHub já revogou?
A documentação diz que o GitHub revoga automaticamente os tokens de acesso pessoal (PAT) do GitHub que vazam em repositório público. Para segredos de provedores parceiros que vazam em público, o GitHub avisa o provedor, que pode agir.
Dica
Recomendação do guia: não espere por isso. Revogue você mesmo e confirme no painel que a chave antiga deixou de funcionar.
Passo 2: confira se houve uso indevido
Uma chave exposta pode ter sido usada antes de você revogá-la. A documentação manda checar se houve acesso não autorizado enquanto o segredo esteve exposto. No tutorial, essa etapa vem depois de revogar e atualizar a chave.
- No painel ou nos registros de auditoria do provedor da chave. A documentação cita o AWS CloudTrail como exemplo de registro que mostra se uma credencial vazada foi usada.
- Nos registros do GitHub: o log de segurança da sua conta pessoal ou o log de auditoria da organização, procurando eventos ligados ao segredo. O seu papel define o que você consegue ver.
Dica
Recomendação do guia: procure uso em horários em que você não usou o serviço, consumo ou cobrança acima do normal e recursos ou chaves que você não criou. Se achar algo assim, fale com o suporte do provedor.
Passo 3: limpe o histórico, com cuidado
Mesmo com a chave revogada e trocada, ela pode continuar no histórico de commits. A documentação diz que, idealmente, você deve procurar e remover todas as ocorrências do segredo no repositório.
Nota
Limpar é o ideal, mas revogar pode bastar. A página oficial de remoção diz que, depois que o segredo é revogado ou trocado, isso pode ser suficiente para resolver o problema.
Atenção
Limpar o histórico reescreve o histórico e afeta quem tem cópia do repositório. A documentação o descreve como um processo destrutivo e que atrapalha quem trabalha no projeto, e que envolve forçar o envio (force push) para o repositório. A página de remoção diz que o histórico pode ser limpo se você coordenar com cuidado com todas as pessoas que clonaram o repositório.
A ferramenta que a documentação usa é o git-filter-repo. É preciso uma versão com a opção --sensitive-data-removal, ou seja, a versão 2.47 ou mais. A página mostra a instalação com Homebrew:
brew install git-filter-repoEm outro sistema, procure as instruções de instalação do git-filter-repo e confira se a versão instalada é a 2.47 ou mais.
Clone o repositório numa pasta nova e entre nela. Troque pelos seus dados:
git clone https://github.com/SEU-USUARIO/SEU-REPOSITORIO
cd SEU-REPOSITORIOPara apagar de todo o histórico um arquivo que continha a chave, como o .env, use o caminho dele no Git:
git-filter-repo --sensitive-data-removal --invert-paths --path .envSe o arquivo já foi movido ou renomeado alguma vez, a página manda repetir o --path para cada caminho antigo ou rodar o comando de novo. Para trocar um texto dentro de arquivos em vez de apagar o arquivo, ela mostra a opção --replace-text com um arquivo de lista. A página não detalha o formato desse arquivo, então consulte o manual do git-filter-repo antes de usar.
Confira o resultado antes de enviar. A página manda verificar que tudo o que você queria remover sumiu, mas não explica como. Recomendação do guia: procure o começo da chave em todo o histórico. O comando não deve mostrar nenhum commit. Explicação geral de Git: o -S procura commits em que o texto informado foi adicionado ou removido, e o --all olha todas as branches e tags. Troque sk-EXEMPLO- pelo começo da sua chave:
git log --all --oneline -S"sk-EXEMPLO-"O próximo passo não tem volta. Quando tiver certeza, envie a versão limpa para o GitHub, sobrescrevendo o repositório:
git push --force --mirror originEnvios para refs/pull/ vão falhar, e isso é esperado, porque o GitHub marca essas referências como somente leitura. Se outras referências falharem, a página diz que provavelmente há proteção de branch ligada naquela branch.
Atenção
O --force descarta mudanças que outras pessoas tenham feito nessas referências enquanto você limpava o repositório.
Depois da limpeza, avise quem tem cópia
- Quem clonou antes da reescrita ainda tem os dados antigos. A página manda descartar o clone e clonar de novo.
- Quem rodar
git pulle depoisgit pushcom uma cópia antiga pode trazer a chave de volta. - Quem criou branches a partir do histórico antigo deve fazer rebase, e não merge. Um merge pode reintroduzir o histórico que você acabou de limpar.
O que a limpeza não alcança
Segundo a documentação, se você só reescreve o histórico e faz o envio forçado, os commits com o dado sensível ainda podem estar acessíveis em outros lugares:
- Em qualquer clone ou fork do repositório.
- Diretamente pelo hash SHA-1 do commit, em visualizações em cache no GitHub.
- Em pull requests que referenciam esses commits.
Você não consegue remover os dados dos clones de outras pessoas. Se o commit existe em algum fork, ele continua acessível lá, e o GitHub não pode fornecer o contato dos donos desses forks. As visualizações em cache e as referências em pull requests podem ser removidas de forma permanente, e isso passa pelo Suporte do GitHub.
O Suporte do GitHub só ajuda com dados sensíveis, e apenas quando considera que o risco não pode ser reduzido trocando as credenciais afetadas. Leitura do guia, fora da documentação: é a revogação do passo 1 que protege você. A limpeza reduz a exposição, mas não apaga todas as cópias.
Como evitar que aconteça de novo
A documentação do GitHub diz que o foco com segredos deve ser evitar o vazamento. Estas práticas ajudam.
Chave fora do código e `.env` fora do Git
Guarde a chave num arquivo .env, ignorado pelo Git com o .gitignore, e leia o valor por variável de ambiente, como na parte A da seção "Se o envio foi bloqueado". A documentação recomenda usar variáveis de ambiente em vez de escrever segredos no código.
Recomendação do guia: crie também um .env.example, com os nomes das variáveis e valores de mentira, para quem usar o projeto saber o que preencher. Esse arquivo pode ir para o Git.
API_KEY=cole-a-chave-aquiA documentação também recomenda trocar os segredos com regularidade, para reduzir o impacto de um vazamento.
Ative as proteções do GitHub
- Na sua conta: confira se "Push protection for yourself" está ativada, como na seção "A proteção de push do GitHub". A documentação recomenda ativá-la para evitar o envio de segredos com suporte a qualquer repositório público.
- No repositório: a documentação recomenda ativar a proteção de push no repositório, se ainda não estiver. Podem fazer isso donos do repositório, donos da organização, gerentes de segurança e quem tem o papel admin.
- Secret scanning: em repositório público, ele roda automaticamente e de graça. Em repositório privado de organização, está disponível com o GitHub Secret Protection ativado no GitHub Team ou no GitHub Enterprise Cloud.
Para ativar a proteção de push no repositório:
- Abra a página principal do repositório e clique em Settings.
- Na barra lateral, em "Security and quality", clique em "Advanced Security".
- Se o Secret Protection ainda não estiver ativado, clique em "Enable" ao lado dele.
- Na seção "Secret Protection", clique em "Enable" ao lado de "Push protection".
Nota
A proteção de push do repositório exige o GitHub Secret Protection. Se as opções não aparecerem para você, o recurso pode não estar disponível no seu plano ou você pode não ter o papel necessário. Recomendação do guia: confirme na documentação do GitHub antes de contar com ele.
Antes de confiar neste guia
- O texto das páginas do GitHub Docs foi conferido em 09/11/2026, na versão GitHub.com. A documentação muda, então reconfira antes de agir.
- A documentação consultada descreve a proteção de push do usuário para repositórios públicos. Ela não diz nada sobre essa proteção em repositório privado, e este guia não promete nada sobre isso.
- Os comandos de limpeza reescrevem o histórico e não têm volta. Faça numa cópia nova do repositório e combine antes com quem trabalha nele.
- As chaves deste guia são falsas. Nunca cole uma chave real em guia, chat, print ou issue.
- Os trechos marcados como "Recomendação do guia" e as explicações gerais de Git não vêm da documentação do GitHub.
- Este guia é conteúdo educativo e independente, sem vínculo com o GitHub.
Fonte
Documentação oficial do GitHub (versão GitHub.com). Conferida em 09/11/2026. O comportamento pode mudar em versões futuras.
Push protection: docs.github.com/en/code-security/concepts/secret-security/push-protection.
Managing push protection for users: docs.github.com/en/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/push-protection-for-users.
Working with push protection from the command line: docs.github.com/en/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-from-the-command-line.
Remediating a leaked secret in your repository: docs.github.com/en/code-security/tutorials/remediate-leaked-secrets/remediating-a-leaked-secret.
Removing sensitive data from a repository: docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository.
Enabling push protection for your repository: docs.github.com/en/code-security/secret-scanning/enabling-secret-scanning-features/enabling-push-protection-for-your-repository.
Secret scanning: docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning.
Ignoring files: docs.github.com/en/get-started/git-basics/ignoring-files.