Guias de Segurança

Detenha segredos antes do commit com o gitleaks: pegue vazamentos de chave de API antes do push

Uma chave de API comitada fica no histórico do Git. Como o gitleaks detém segredos com hook de pre-commit e CI, e por que ainda é preciso revogar a chave.

Publicado 2026-06-12 Atualizado 2026-10-06 16 min de leitura
Nesta página

Para: qualquer pessoa usando Git em desenvolvimento solo ou de equipe pequena, preocupada com "e se eu comitar uma chave de API por acidente?" Sem mecânica de invasor aqui — apenas a maquinaria para impedir que segredos vazem do seu próprio repositório.

A visão deste site: o .gitignore sozinho não protege segredos

"Meu .env está no .gitignore, então estou bem" é uma fala comum, e ela deixa casos de fora. O .gitignore só impede que arquivos novos sejam rastreados; ele não consegue pegar segredos já comitados, os adicionados às pressas com git add -f, ou nomes inesperados como .env.local.bak. Ele previne só algumas das formas pelas quais um segredo entra. Você precisa de algo que de fato olhe o conteúdo dos commits e sinalize "strings com cara de segredo" — um detector. É para isso que o gitleaks serve.

Por que deter "antes do commit"

Segredos são perigosos porque o Git mantém o histórico para sempre. Apague-o do arquivo mais recente e ele permanece em commits passados. E no momento em que é enviado, esse histórico é copiado para outras máquinas, servidores e logs de CI.

fica no histórico
some do mais recente, ainda em commits passados
push = espalha
copiado para outras máquinas, servidores, logs de CI
precisa revogar
uma chave já vazada só pode ser reemitida
duas verificações
detê-lo no pre-commit e no CI

Então a defesa de segredos é, na verdade, sobre prevenção antes do vazamento, não recuperação depois dele. É a mesma ideia do inventário "não deixe segredos num diretório público" (→ o inventário da raiz web), aplicada ao código.

Em quais etapas detectar segredos

No caminho que um segredo percorre do código ao mundo, você pode colocar duas verificações: no momento do commit local e logo antes de ele ser compartilhado (CI).

segredo no código

chave de API, chave, token

→

verificação 1: pre-commit

detecta & aborta localmente no commit

→

verificação 2: CI / cron

detecta após o push, antes do merge/deploy

→

público / compartilhado

daqui em diante, trate como vazado

O caminho do vazamento e duas verificações. O pre-commit o detém localmente; o CI o detém antes do merge/deploy.

Como integrar o gitleaks

1

Varra o histórico existente primeiro

Na adoção, varra todo o histórico do repo uma vez com gitleaks git (gitleaks detect em versões anteriores à v8.19.0). Encontrar segredos deixados em commits passados é o primeiro trabalho. Qualquer coisa encontrada aqui é, como abaixo, presumida como precisando de revogação.
2

Adicione a verificação 1 com um hook de pre-commit

Rode gitleaks git --pre-commit --staged (antes, gitleaks protect --staged) em cada commit para abortar na hora qualquer commit que contenha um segredo. Adicione-o a um framework de pre-commit (.pre-commit-config.yaml) para que a mesma verificação se aplique a todos, localmente.
3

Adicione a verificação 2 no CI / cron

Hooks podem ser desativados por cada pessoa, então verifique de novo antes de qualquer coisa ser compartilhada. Rode gitleaks git como um job de CI — ou, em setups auto-hospedados, como uma varredura periódica — para pegar o que escapa (a mesma mentalidade de monitoramento por máquina das auditorias de dependências).
4

Ajuste falsos positivos no .gitleaks.toml

Quando chaves de teste fictícias ou valores de exemplo o disparam, ajuste regras e a allowlist no .gitleaks.toml. A prática certa é não "suprimir o aviso", mas "registrar por que é seguro" — uma exclusão sem justificativa pode causar o próximo incidente.

Na detecção, 'revogar' vem primeiro; reescrever o histórico vem depois

Quando você encontra um segredo que foi comitado e enviado, a prioridade máxima é revogar e reemitir (rotacionar) essa chave ou token. Apagá-lo do histórico com git filter-repo importa, mas é só limpeza para "parar de se espalhar mais". Suponha que um segredo que chegou a um repo público, a um fork, a um log de CI ou ao clone de outra pessoa é irrecuperável — invalide-o primeiro, depois limpe o histórico. Inverta a ordem e ele é usado enquanto você ainda está apagando.

Confiar no .gitignore

  • só impede novo rastreamento
  • segredos já comitados não são detectados
  • impotente contra git add -f ou nomes de arquivo estranhos
  • não consegue verificar "eu não quis adicionar isso"

gitleaks (detecção + prática de revogação)

  • de fato inspeciona a árvore de trabalho e o conteúdo do histórico
  • o detém com duas verificações: pre-commit e CI
  • na detecção, um procedimento que vai até a revogação
  • falsos positivos excluídos com uma justificativa registrada

Qual comando usar (v8.19.0 e posteriores)

O gitleaks reorganizou seus comandos na v8.19.0. Os antigos detect e protect ainda rodam, mas estão descontinuados e não aparecem mais na ajuda. Para uma configuração nova, use estes:

ComandoO que varreUso típico
gitleaks gitHistórico de commits do GitPrimeira varredura do histórico completo, CI, varreduras agendadas
gitleaks git --pre-commit --stagedAs mudanças que você está prestes a comitar (staged)Hook de pre-commit (o hook oficial roda exatamente isto)
gitleaks dirPastas e arquivos, inclusive os que não estão no GitPastas web públicas, backups, zips de release descompactados
gitleaks stdinTexto recebido por pipe na entrada padrãoSaída ou logs de outros comandos

O gitleaks sai com código 1 quando encontra pelo menos um vazamento e 0 quando não encontra nenhum, então jobs de CI e cron podem falhar com base nesse código de saída. Adicione --redact para que o segredo em si nunca vá parar na saída nem nos logs.

Exemplo de configuração: hook de pre-commit e GitHub Actions

Com o framework pre-commit, coloque este arquivo na raiz do repositório. Defina rev como a versão mais recente ao adicioná-lo (v8.30.1 em outubro de 2026).

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.1
    hooks:
      - id: gitleaks

Além de gitleaks (compilado com Go), o id pode ser gitleaks-docker (roda no Docker) ou gitleaks-system (usa um gitleaks já instalado na máquina). Depois, cada pessoa roda isto na própria máquina:

pip install pre-commit        # install pre-commit itself
pre-commit install            # register the hook in this repo (once per clone)
pre-commit run --all-files    # check every file once, right after registering
pre-commit autoupdate         # run now and then to move rev to a newer release

Para CI no GitHub, existe uma GitHub Action oficial. Ela precisa do histórico completo, então faça o checkout com fetch-depth: 0.

# .github/workflows/gitleaks.yml
name: gitleaks
on:
  pull_request:
  push:
  schedule:
    - cron: "0 4 * * *"
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v3
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

Para repositórios de uma conta de organização, a Action precisa de uma chave de licença (GITLEAKS_LICENSE). O README oficial diz que a chave é gratuita em gitleaks.io e não é necessária para contas pessoais. Num servidor Git auto-hospedado ou num CI que não seja o do GitHub, rodar gitleaks git --redact dentro do job faz a mesma coisa.

Onde verificar: quatro pontos comparados

Qualquer verificação isolada deixa uma brecha. Colocar lado a lado o que cada uma detém, e onde ela vaza, mostra por que combiná-las.

OndeDetém emO que cobreBrechas e limites
Hook de pre-commit (local)Antes do commitMudanças stagedPulado com git commit --no-verify ou SKIP=gitleaks. Clonar um repo não instala o hook
CI (GitHub Actions etc.)Antes do merge ou do deployCommits enviados e históricoO push já aconteceu. Num repo público, trate como vazado
Varredura agendada (cron)Encontra depoisHistórico completo do repositórioAtraso até a descoberta. Pega o que regras novas encontram em commits antigos
Proteção de push do GitHubNo push para o GitHubTipos de segredo que o GitHub suportaPode ser contornada informando um motivo. Não faz nada em outros servidores Git

A proteção de push do GitHub para usuários vem ligada por padrão em pushes para repositórios públicos. É uma rede de segurança gratuita, mas não detém commits locais, e chaves em formatos não suportados ou strings de conexão montadas à mão podem passar (mais em por que credenciais expostas no GitHub continuam válidas, em inglês). O gitleaks cobre a etapa anterior a isso e tudo o que está fora do GitHub.

Como verificar a sua própria configuração

Configurar uma vez não significa que está rodando. No seu próprio repositório, verifique isto em ordem.

1

Verifique a versão do gitleaks

Rode gitleaks version. Qualquer versão anterior à v8.19.0 não tem gitleaks git nem os outros comandos novos, então atualize.

2

Verifique se o hook está registrado

Procure por .git/hooks/pre-commit. Se git config --get core.hooksPath apontar para outra pasta, olhe lá. O Git não copia hooks quando você clona, então rode pre-commit install de novo numa máquina nova ou num clone novo.

3

Varra o histórico completo uma vez

Na raiz do repositório, rode gitleaks git --redact -v. Sem achados, o código de saída é 0. Se algo for encontrado, use o nome do arquivo e o commit na saída para verificar, no console de quem emitiu a chave, se ela ainda é válida.

4

Varra também pastas fora do Git

A pasta pública do seu servidor, os backups e o conteúdo dos zips que você distribui são invisíveis para uma varredura do histórico do Git. Verifique-os com gitleaks dir (caminho da pasta) --redact (→ o inventário do diretório público).

5

Verifique se o .env já foi comitado

Rode git log --all --oneline -- .env para ver se algum commit passado tocou no .env. Se aparecer uma única linha que seja, o conteúdo daquele momento está no histórico.

Lidando com falsos positivos

Chaves de teste fictícias e exemplos na documentação costumam ser sinalizados. Há três formas de excluí-los; use a mais estreita que resolva.

  • Por linha: adicione um comentário gitleaks:allow naquela linha
  • Por achado: adicione a impressão digital (fingerprint) mostrada na saída ao .gitleaksignore na raiz do repositório (o README marca isso como experimental)
  • Por arquivo ou padrão: adicione à allowlist no .gitleaks.toml

Se você escrever o seu próprio .gitleaks.toml, coloque useDefault = true sob [extend] para manter as regras padrão. Uma configuração só com regras próprias descarta, sem avisar, as chaves que as regras padrão teriam pegado.

Se um repositório antigo tem muitos achados existentes, passe um relatório anterior para --baseline-path para que só achados novos sejam reportados. Mas revogue primeiro as chaves desse relatório. Colocar uma chave na baseline não a torna segura.

Erros comuns e como corrigi-los

  • Achar que o arquivo de configuração basta: o hook não faz nada até alguém rodar pre-commit install. Faça todos rodarem e rode a mesma verificação no CI como segunda camada.
  • Acostumar-se com --no-verify: torne a verificação do CI uma condição obrigatória para o merge, para que um hook pulado ainda seja pego.
  • Imprimir segredos nos logs do CI: adicione --redact. Logs de CI também são lidos por muita gente.
  • Varrer um clone raso (shallow clone) no CI: só o commit mais recente é verificado e segredos no histórico passam despercebidos. Defina fetch-depth: 0.
  • Parar depois de apagar do histórico: o próprio guia do GitHub coloca revogar ou rotacionar o segredo como primeiro passo. Cópias em forks, clones e caches não podem ser removidas.
  • Colocar uma chave real na allowlist como "falso positivo": escreva o motivo num comentário e confira na revisão.

Um caso real: uma chave de acesso deixada pública

Em 7 de outubro de 2022, a Toyota Motor Corporation anunciou que parte do código-fonte do site para usuários do seu serviço de carro conectado T-Connect tinha ficado pública no GitHub. Segundo o anúncio da empresa:

  • Em dezembro de 2017, a empresa contratada que desenvolvia o site enviou por engano parte do código-fonte para uma conta do GitHub configurada como pública
  • O código continha uma chave de acesso ao servidor de dados que armazenava informações de clientes
  • O código foi tornado privado em 15 de setembro de 2022, e a chave de acesso foi trocada em 17 de setembro
  • 296.019 endereços de e-mail e números de controle de clientes foram afetados. Os logs de acesso não mostraram uso por terceiros, mas a empresa disse que não podia descartar isso por completo

São cerca de cinco anos entre o envio e a remoção. E aconteceu fora dos repositórios da própria empresa, na conta de uma contratada. Um scanner nos seus próprios repos não alcança todos os lugares para onde o seu código vai parar; então limite também o que cada chave pode fazer e rotacione chaves periodicamente. E mesmo aqui, a chave foi trocada dois dias depois de o código ser retirado: encontre, depois substitua a chave.

Um repositório privado também não é lugar seguro para segredos. No caso da CAMPFIRE em 2026, segundo a empresa, uma credencial do GitHub usada indevidamente foi o ponto de partida, e informações visíveis no GitHub foram usadas para obter credenciais de nuvem (→ o vazamento da CAMPFIRE, em inglês). Mantenha segredos fora de repos privados também e varra-os com o gitleaks periodicamente.

O que este site faz

A regra básica deste site é manter segredos totalmente fora do Git — strings de conexão e chaves de API vivem só em configuração protegida no servidor (um arquivo env com permissão restrita), nunca em texto puro no repo ou em notas de handoff (→ manter segredos fora do git / Git auto-hospedado vs GitHub). Além disso, sobrepomos detectores no pressuposto de que humanos sempre escorregam. O design garante "não coloque", e uma varredura como o gitleaks pega "entrou mesmo assim" — essas duas camadas são a defesa deste site contra vazamentos de segredo. O princípio de lidar com segredos em si é o mesmo de arquivos .env e segredos e armazenando senhas com segurança.

Leia a seguir

Fontes

  • gitleaks (repositório oficial), README: comandos (git, dir, stdin), descontinuação de detect/protect na v8.19.0, códigos de saída, --redact, gitleaks:allow, .gitleaksignore, --baseline-path, extensão de configuração — github.com/gitleaks/gitleaks / definições oficiais do hook — .pre-commit-hooks.yaml / Releases
  • gitleaks-action (GitHub Action oficial), README: exemplo de workflow e chave de licença — github.com/gitleaks/gitleaks-action
  • Documentação do pre-commit (install, run --all-files, autoupdate, SKIP) — pre-commit.com
  • Documentação do Git, "githooks" (o hook pre-commit e --no-verify) — git-scm.com
  • GitHub Docs, "About push protection" — docs.github.com / "Removing sensitive data from a repository" — docs.github.com
  • Toyota Motor Corporation, aviso sobre o possível vazamento de endereços de e-mail de clientes (7 de outubro de 2022, em japonês) — global.toyota

FAQ

QO que é o gitleaks?
A

Uma ferramenta gratuita que varre a árvore de trabalho e o histórico de commits de um repositório Git para detectar se segredos — chaves de API, chaves privadas, tokens — foram comitados. Ele encontra 'strings com cara de segredo' com regras de regex e entropia de string (aleatoriedade), e pode rodar como um hook de pre-commit ou no CI para verificações automáticas.

QColocar no .gitignore não protege os segredos?
A

Não o suficiente. O .gitignore só impede 'novo rastreamento' — ele não consegue detectar segredos já comitados, nem os adicionados à força com git add -f. Ele previne só alguns acidentes, então combine-o com um detector como o gitleaks tanto no pre-commit quanto no CI.

QE se eu acidentalmente comitei e enviei um segredo?
A

Trate esse segredo como vazado. A prioridade máxima não é reescrever o histórico, mas revogar e rotacionar (reemitir) a chave ou token exposto. Suponha que um segredo que chegou a um repo público ou a um log não pode ser chamado de volta — invalide-o primeiro, depois limpe o histórico e adicione a prevenção (gitleaks).

Qgitleaks detect e gitleaks protect ainda funcionam?
A

Ainda rodam, mas foram descontinuados na v8.19.0 e não aparecem mais na ajuda. Os comandos atuais são gitleaks git (varre o histórico de commits), gitleaks dir (varre pastas e arquivos) e gitleaks stdin (varre a entrada recebida por pipe). A verificação de pre-commit agora é gitleaks git --pre-commit --staged, que é também o que o hook oficial de pre-commit roda. Use os comandos novos ao configurar.

QSe a proteção de push do GitHub está ligada, ainda preciso do gitleaks?
A

Eles cobrem coisas diferentes, então use os dois. A proteção de push do GitHub para usuários vem ligada por padrão em pushes para repositórios públicos, mas pode ser contornada escolhendo um motivo e não faz nada por commits locais nem por servidores Git que não sejam o GitHub. O gitleaks detém o segredo na sua máquina antes do commit e roda as mesmas regras num servidor Git auto-hospedado ou em qualquer CI.

QComo faço o gitleaks parar de sinalizar uma chave de teste fictícia?
A

Há três formas: adicionar um comentário gitleaks:allow naquela linha, colocar a impressão digital (fingerprint) do achado no .gitleaksignore ou excluir arquivos ou padrões com uma allowlist no .gitleaks.toml. Qualquer que seja a forma, deixe um comentário dizendo por que é seguro. A falha que mais se deve evitar é colocar uma chave real na allowlist como falso positivo.