Keyhound
Detector de credenciais expostas em código, com cobertura para serviços
brasileiros que ferramentas como gitleaks e trufflehog não reconhecem:
Mercado Pago, Asaas, Pagar.me, Cielo, PagSeguro, chave Pix, certificado
digital A1 e a chave service_role do Supabase.
Por que existe
Durante o desenvolvimento é comum colar a chave direto no arquivo para testar — e esquecer. O código vai para o repositório e a chave vai junto. Há robôs varrendo o GitHub atrás exatamente disso: o intervalo entre publicar e a chave ser usada por terceiros costuma ser de minutos.
Remover a chave do arquivo não resolve: ela continua no histórico do Git, recuperável por qualquer pessoa com acesso ao repositório.
Instalação
pip install keyhound
Requer Python 3.11 ou superior.
Uso
keyhound scan . # varre o diretório atual
keyhound scan ./src -m high # só severidade alta ou acima
keyhound scan . -f json # saída para pipeline
keyhound scan . -f sarif # saída para o GitHub code scanning
keyhound scan . --fail-on critical # sai com código 1 se achar crítico
keyhound history . # varre todo o histórico do git
keyhound history . -n 100 # só os 100 commits mais recentes
keyhound history . -f json
O valor do segredo é sempre mascarado na saída — na tela, no JSON, no SARIF e no relatório.
Validação ativa
keyhound scan . --validate
Consulta o próprio serviço para saber se a credencial encontrada ainda funciona. Separa o que é histórico do que é incidente: uma chave ativa precisa ser revogada agora.
Suportado hoje: GitHub, Slack, Stripe e Mercado Pago. As chamadas são de leitura, feitas por HTTPS direto no endpoint oficial de cada serviço, e só acontecem com a flag explícita.
Use apenas em credenciais suas ou que você tenha autorização para testar.
Relatório para não técnicos
keyhound report . -o relatorio.html --client "Nome da Empresa"
keyhound report . -o relatorio.html --validate
Gera um arquivo HTML para o dono da empresa, o jurídico ou a auditoria: resumo em linguagem simples, tabela de achados, o que fazer em cada caso e a leitura pela LGPD (Art. 46 e Art. 48). Abre em qualquer navegador e pode ser impresso ou salvo em PDF.
O relatório é técnico e não constitui parecer jurídico. Trate-o como confidencial: ele aponta onde estão as falhas.
O que detecta
Globais — AWS, GitHub, Slack, chave privada PEM, JWT, string de conexão de banco, Google API, Stripe, senha e token em atribuição literal.
Brasileiros — Mercado Pago, Asaas, Pagar.me/Stone, MerchantKey da
Cielo, token do PagSeguro/PagBank, service_role e chave secreta do
Supabase, chave Pix aleatória (EVP) e senha de certificado A1.
A regra do service_role merece destaque: essa chave ignora todas as
políticas de Row Level Security do Supabase. Vazada no frontend, expõe o
banco inteiro. É visualmente idêntica à chave anon, que é pública e
inofensiva — o Keyhound distingue as duas.
Pre-commit hook
Bloqueia o commit automaticamente quando encontra credencial. No
.pre-commit-config.yaml do seu projeto:
repos:
- repo: https://github.com/felipedelyra-arch/keyhound
rev: v0.3.0
hooks:
- id: keyhound
Depois:
pip install pre-commit
pre-commit install
A partir daí, todo git commit passa pelo Keyhound. Se encontrar algo de
severidade média ou acima, o commit é recusado.
GitHub Action
No .github/workflows/security.yml do seu projeto:
name: Secret scan
on: [push, pull_request]
jobs:
keyhound:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: felipedelyra-arch/keyhound@v0.3.0
with:
fail-on: critical
Para varrer também o histórico completo:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: felipedelyra-arch/keyhound@v0.3.0
with:
scan-history: "true"
O fetch-depth: 0 é necessário porque, por padrão, o checkout traz
apenas o último commit.
Achados na aba Security
Com a saída SARIF, os achados aparecem na aba Security → Code scanning do repositório, anotados na linha do código:
permissions:
contents: read
security-events: write
jobs:
keyhound:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install keyhound
- run: keyhound scan . --format sarif > keyhound.sarif
continue-on-error: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: keyhound.sarif
category: keyhound
Reduzindo ruído
Ferramenta que grita demais é desinstalada. O Keyhound filtra em três camadas antes de reportar:
- caminhos listados no
.keyhoundignore - valores que são claramente placeholder (
xxxx,<your-key>,${API_KEY},CHANGEME) - chaves de exemplo que circulam em documentação oficial
Crie um .keyhoundignore na raiz do projeto:
tests/fixtures/
**/*.lock
docs/exemplos/
Desenvolvimento
git clone https://github.com/felipedelyra-arch/keyhound.git
cd keyhound
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
Contribuindo
Veja CONTRIBUTING.md. Regras novas para serviços brasileiros são especialmente bem-vindas.
Licença
Apache License 2.0 — veja LICENSE.
Release files for keyhound 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| keyhound-0.3.0.tar.gz | 25.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keyhound-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.0 kB
Release files / keyhound-0.3.0.tar.gz
| Download URL | keyhound-0.3.0.tar.gz |
|---|---|
| Size | 25.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6769bb3f591d99f3b9871167935ece6b1c747a62b96eac182628dfb097e742af
|
|
BLAKE2b-256 checksum How to use checksums |
f4cabac92f19467bbb606e5f8b74d8ec3ab98286ad864698aa2d5f8d5198c180
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / keyhound-0.3.0-py3-none-any.whl
| Download URL | keyhound-0.3.0-py3-none-any.whl |
|---|---|
| Size | 26.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
82b76e7909fa53f3095ac56bfd5281a5920279b6db8ff27ea391561c421b90ed
|
|
BLAKE2b-256 checksum How to use checksums |
10bee7a1e61910955376a483ddf7c085ec41ded8abc7c2fea1ed88fcfc866f13
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|