๐ KeyHunter
Fast GitHub API key leak scanner written in Rust. Find exposed API keys and help developers secure their secrets.
Features
- ๐ Blazing Fast: Parallel scanning with token rotation
- ๐ฏ 45+ Providers: AI/LLM, Cloud, Payment, Database, and more
- ๐ Rate Limit Bypass: Use multiple GitHub tokens for unlimited scanning
- ๐ Smart Search: Finds keys in ANY file, not just .env
- โ Key Verification: Test if found keys are still active (20+ providers)
- ๐ฏ Verified-Only Mode: Use
-Vto scan+verify and output only active keys - ๐ Clean Output: Table, JSON, or CSV formats
- ๐พ Auto-save: Results saved with timestamps
- โน๏ธ Graceful Stop: Press Ctrl+C anytime to stop and save collected results
- ๐ Verbose Mode: See detailed logs of every file and URL being processed
- ๐ณ Docker Ready: No Rust installation required - just use Docker
Why KeyHunter?
Smart Search Strategy
Most tools search for patterns like sk-proj- which appear in tutorials, docs, and examples. KeyHunter uses unique pattern segments that only exist in real keys:
| Provider | Others Search | KeyHunter Searches |
|---|---|---|
| OpenAI | sk-proj- |
T3BlbkFJ (unique Base64 in all keys) |
| Anthropic | sk-ant- |
sk-ant-api03- (real key prefix) |
| Stripe | sk_live_ |
sk_live_ + length validation |
Multi-Query Approach
For each provider, KeyHunter runs multiple searches:
- Pattern search - Unique identifier (
T3BlbkFJ) - Filename filter - Pattern +
filename:.env - Env var search -
OPENAI_API_KEY
This catches keys that single-pattern tools miss.
False Positive Filtering
KeyHunter automatically skips placeholder keys:
sk-proj-xxxxxxxxxxxxxxxx โ skipped (placeholder)
sk-proj-YOUR_API_KEY_HERE โ skipped (example)
sk-proj-test_1234567890 โ skipped (test key)
sk-proj-T3BlbkFJx8Hn2m... โ โ real key
Modern Provider Coverage
KeyHunter includes AI providers that most tools don't have yet:
| Category | Providers |
|---|---|
| AI / LLM | Anthropic, OpenAI, Google AI, Grok, DeepSeek, Groq, Perplexity, Replicate, HuggingFace, Fireworks, Cohere, Mistral, Together |
| New | Grok (xAI), DeepSeek, Groq, Perplexity |
Offensive vs Defensive
| Tool Type | Purpose | Examples |
|---|---|---|
| Hunters (KeyHunter) | Find leaked keys across ALL public repos | Active scanning |
| Defenders | Scan YOUR repos to prevent leaks | TruffleHog, Gitleaks, git-secrets |
KeyHunter is built for security researchers who need to find exposed keys at scale.
Quick Start
1. Get a GitHub Token
Go to: https://github.com/settings/tokens/new
- Note:
keyhunter - Expiration: 30 days
- Scopes: โ
public_repoonly
Click Generate token and copy it.
2. Configure
Edit config.toml:
[]
= [
"ghp_YOUR_ACTUAL_TOKEN_HERE",
]
3. Choose Your Installation
Option A: With Rust (Native)
# Build (first time takes ~2 min)
# Run
Option B: With Docker (No Rust Required)
# Build image (~3-5 min first time)
# Run
4. Typical Workflow
Option A: Two-step (recommended for large scans)
# Step 1: Scan for keys
# Output: results/findings_20260119_143022.json
# Step 2: Verify which keys are active
# Output: results/verified_20260119_143100.json
# results/verified_20260119_143100_active.json (only active keys)
Option B: One-step with -V (for smaller scans)
# Scan + verify in one command (verifies first 50 keys)
# Output: results/verified_active_20260119_143022.json (only active keys)
# Or verify ALL found keys (caution: may hit rate limits)
Docker Setup
Full Docker documentation for those without Rust installed.
Build & Run
# 1. Setup config
# Edit config.toml with your GitHub token
# 2. Build image (~3-5 min first time)
# 3. Run scan
# With verbose mode
# Show help
# Show patterns
Docker Compose
Simpler syntax using docker-compose:
# Run with docker-compose
# With verbose
# Scan all providers
# Show patterns
Docker Commands Reference
| Command | Description |
|---|---|
docker build -t keyhunter . |
Build image |
docker run keyhunter --help |
Show help |
docker run keyhunter patterns |
List providers |
docker run -v ... keyhunter scan |
Run scan |
docker run -v ... keyhunter scan -V |
Scan + verify (active only) |
docker run -v ... keyhunter verify -i ... |
Verify keys |
docker-compose run keyhunter scan |
Run with compose |
Volume Mounts
| Mount | Purpose |
|---|---|
./config.toml:/app/config.toml |
Your config file |
./results:/app/results |
Save results locally |
Results are saved to your local ./results folder.
Docker Tips
# Create alias for easier usage
# Then just run:
CLI Reference
keyhunter <COMMAND>
COMMANDS:
scan Scan GitHub for leaked API keys
verify Verify if found keys are active
patterns Show all supported providers and patterns
help Show help for a command
keyhunter scan
Scan GitHub for leaked API keys.
Usage:
# Scan all providers
# Scan specific provider
# Verbose mode - see detailed logs
# Custom search query (any GitHub code search)
# Different output formats
# Use different config file
# Combine options
# Verified-only mode - only output active keys
# Combine verbose + verified-only
Options:
| Option | Description | Default |
|---|---|---|
-c, --config <FILE> |
Config file path | config.toml |
-p, --provider <n> |
Provider to scan | all |
-q, --query <QUERY> |
Custom GitHub search query | - |
-o, --output <FORMAT> |
Output: table, json, csv | table |
-v, --verbose |
Show detailed logs (files, URLs, etc.) | false |
-V, --verified-only |
Only save active (verified) keys | false |
--verify-all |
With -V: verify all keys (not just 50) | false |
-h, --help |
Show help | - |
Verified-Only Mode (-V):
Scan and verify in one command - only outputs keys that are confirmed active:
# Scan + verify first 50 keys, output only active
# Scan + verify ALL keys (caution: may hit rate limits)
Note: Without
-V, scan outputs all found keys (unverified). Useverifycommand later to check which are active.
keyhunter patterns
Show all supported providers and their regex patterns.
Usage:
Output:
โญโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโฎ
โ Provider โ Pattern โ Example โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโค
โ Anthropic โ sk-ant-api03-[...]{93} โ sk-ant-api03-xxxxx โ
โ OpenAI โ sk-proj-[...]{48,180} โ sk-proj-xxxxx โ
โ Google AI โ AIza[...]{35} โ AIzaSyDxxxxx โ
โ AWS โ AKIA[0-9A-Z]{16} โ AKIAIOSFODNN7 โ
โ Stripe โ sk_live_[...]{24,99} โ sk_live_xxxxx โ
โ ... โ ... โ ... โ
โฐโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโฏ
keyhunter verify
Verify if found keys are still active by testing against provider APIs.
Tip: For quick scans, use
scan -Vto scan+verify in one step. Use this separateverifycommand when you want more control over batch verification of large result files.
Usage:
# Verify first 50 keys (default, safe)
# Verify only OpenAI keys
# Verify first 100 keys
# Verify ALL keys (careful - may hit rate limits)
# More concurrent requests (faster but riskier)
# Save to specific file
Options:
| Option | Description | Default |
|---|---|---|
-i, --input <FILE> |
Results JSON file (required) | - |
-l, --limit <N> |
Verify first N keys | 50 |
-p, --provider <NAME> |
Verify only this provider | all |
-a, --all |
Verify all keys (ignore limit) | false |
-c, --concurrent <N> |
Parallel requests | 5 |
-o, --output <FILE> |
Save verified results | auto |
-h, --help |
Show help | - |
Output:
๐ Loaded 567 keys from results/findings.json
๐ Verifying 50 keys with 5 concurrent requests
OpenAI 35 keys
Anthropic 10 keys
Stripe 5 keys
โ ACTIVE sk-proj-...xxxx (OpenAI)
โ ACTIVE sk-ant-a...yyyy (Anthropic)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Verification Complete
๐ด 12 keys are ACTIVE (leaked & working!)
๐ข 35 keys are revoked/invalid
๐ก 3 keys had errors (rate limited/timeout)
๐พ Results saved to: results/verified_20260119.json
๐ด Active keys saved to: results/verified_20260119_active.json
Supported Verification:
| Provider | Method | Status |
|---|---|---|
| OpenAI | GET /v1/models | โ |
| Anthropic | POST /v1/messages | โ |
| Google AI | GET /v1/models | โ |
| Groq | GET /v1/models | โ |
| Perplexity | POST /chat/completions | โ |
| HuggingFace | GET /api/whoami-v2 | โ |
| Replicate | GET /v1/account | โ |
| Fireworks | GET /v1/models | โ |
| Cohere | GET /v1/models | โ |
| Mistral | GET /v1/models | โ |
| Together | GET /v1/models | โ |
| DeepSeek | GET /v1/models | โ |
| GitHub | GET /user | โ |
| GitLab | GET /api/v4/user | โ |
| Stripe | GET /v1/balance | โ |
| SendGrid | GET /v3/scopes | โ |
| Mailgun | GET /v3/domains | โ |
| Slack | GET /api/auth.test | โ |
| Discord | GET /users/@me | โ |
| Telegram | GET /getMe | โ |
| Mapbox | GET /tokens/v2 | โ |
| New Relic | GET /v2/users.json | โ |
| Datadog | GET /api/v1/validate | โ |
| AWS | โ ๏ธ Requires secret key pair | โ |
| Twilio | โ ๏ธ Requires Account SID | โ |
| Firebase | โ ๏ธ Requires project ID | โ |
Provider Names
Use these names with -p flag:
AI / LLM:
anthropic, openai, google, grok, deepseek, huggingface,
replicate, perplexity, groq, fireworks
Cloud:
aws
Payment:
stripe_live, stripe_restricted, paypal, square
Communication:
twilio, sendgrid, mailgun, mailchimp
Developer Platforms:
github_token, gitlab, npm, pypi
Social / Messaging:
slack_bot, slack_user, slack_webhook, discord,
discord_webhook, telegram
Database:
mongodb, postgres, mysql, redis
Other:
firebase, mapbox, sentry, newrelic, planetscale,
doppler, private_key
Supported Providers (45+)
AI / LLM
| Provider | Pattern | Search Term |
|---|---|---|
| Anthropic | sk-ant-api03-... |
sk-ant-api03- |
| OpenAI | sk-proj-... |
T3BlbkFJ |
| Google AI | AIza... |
AIzaSy |
| xAI Grok | xai-... |
xai- |
| DeepSeek | sk-[hex] |
DEEPSEEK_API_KEY |
| HuggingFace | hf_... |
hf_ |
| Replicate | r8_... |
r8_ |
| Perplexity | pplx-... |
pplx- |
| Groq | gsk_... |
gsk_ |
| Fireworks | fw_... |
fw_ |
Cloud & Infrastructure
| Provider | Pattern |
|---|---|
| AWS | AKIA... |
| Azure | ...(86 chars)== |
Payment
| Provider | Pattern |
|---|---|
| Stripe | sk_live_... |
| Square | sq0csp-... |
| PayPal | access_token$... |
Communication
| Provider | Pattern |
|---|---|
| Twilio | SK[hex]{32} |
| SendGrid | SG.... |
| Mailgun | key-... |
| Mailchimp | ...-us14 |
Developer Platforms
| Provider | Pattern |
|---|---|
| GitHub | ghp_..., github_pat_... |
| GitLab | glpat-... |
| NPM | npm_... |
| PyPI | pypi-... |
Social / Messaging
| Provider | Pattern |
|---|---|
| Slack Bot | xoxb-... |
| Slack User | xoxp-... |
| Slack Webhook | hooks.slack.com/... |
| Discord | Bot tokens |
| Discord Webhook | discord.com/api/webhooks/... |
| Telegram | 123456789:ABC... |
Database
| Provider | Pattern |
|---|---|
| MongoDB | mongodb+srv://... |
| PostgreSQL | postgres://... |
| MySQL | mysql://... |
| Redis | redis://... |
Other Services
| Provider | Pattern |
|---|---|
| Firebase | AAAA...:... |
| Mapbox | pk.eyJ... |
| Sentry | https://...@sentry.io |
| New Relic | NRAK-... |
| PlanetScale | pscale_tkn_... |
| Doppler | dp.pt.... |
| Private Key | -----BEGIN PRIVATE KEY----- |
Output Examples
Normal Mode (default)
๐ Scanning 1 provider(s), 6 queries total
โน Press Ctrl+C to stop and save results
โ Provider: OpenAI (OpenAI API Key)
โฉ Query 1/6: T3BlbkFJ
โ [โโโโโโโโโโโโโโโโโโโโโโโโโ] 3/10 pages | 28 keys
โณ 282 keys found
โฉ Query 2/6: T3BlbkFJ filename:.env
โณ 285 keys found
โ Running total: 567 unique keys
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Found 567 potential leaked keys
Verified-Only Mode (-V)
๐ Scanning 1 provider(s), 6 queries total
โน Press Ctrl+C to stop and save results
โ Provider: OpenAI (OpenAI API Key)
โฉ Query 1/6: T3BlbkFJ
โณ 282 keys found
โ Running total: 248 unique keys
๐ Verifying keys...
๐ Verifying 50 keys (--verified-only mode)
โ ACTIVE sk-proj-SL...apsA (OpenAI)
โ ACTIVE sk-proj-KK..._uIA (OpenAI)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Found 4 ACTIVE keys
๐พ Active keys saved to: results/verified_active_20260119_143022.json
Verbose Mode (-v)
๐ Scanning 1 provider(s), 6 queries total
โน Press Ctrl+C to stop and save results
๐ Verbose mode enabled - showing detailed logs
โ Provider: OpenAI (OpenAI API Key)
โฉ Query 1/6: T3BlbkFJ
ยท Page 1/10 - 30 files to process
โ user/chatbot/.env โ 2 key(s)
https://github.com/user/chatbot/blob/main/.env
โ dev/project/config.js โ 1 key(s)
https://github.com/dev/project/blob/main/config.js
ยท corp/docs/README.md โ no keys
โ startup/api/.env.local โ 3 key(s)
https://github.com/startup/api/blob/main/.env.local
โณ Page 1 complete: 28 keys found
ยท Page 2/10 - 30 files to process
โ another/repo/.env โ 1 key(s)
https://github.com/another/repo/blob/main/.env
...
โณ 282 keys found
โฉ Query 2/6: T3BlbkFJ filename:.env
ยท Page 1/10 - 30 files to process
...
โ Running total: 567 unique keys
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Found 567 potential leaked keys
Graceful Stop (Ctrl+C)
Press Ctrl+C anytime during scanning to stop and save all collected results.
๐ Scanning 1 provider(s), 6 queries total
โน Press Ctrl+C to stop and save results
โ Provider: OpenAI (OpenAI API Key)
โฉ Query 1/6: T3BlbkFJ
โณ 282 keys found
โฉ Query 2/6: T3BlbkFJ filename:.env
^C
โ Interrupted! Saving collected results...
๐พ Saved 450 keys to: results/findings_20260119_143022_interrupted.json
Results are saved to *_interrupted.json so you don't lose your progress.
Configuration
Config File: config.toml
[]
= [
"ghp_YOUR_TOKEN_HERE",
]
= 5 # parallel requests
= 500 # delay between requests
[]
= 1000 # max results per query
[]
= "table" # table, json, csv (CLI -o overrides)
= true
= "results"
[]
= true
= true
= true
# ... see config.toml.example for all options
Results Volume
Control how many results to fetch with max_results:
| max_results | Pages | Speed | Keys (approx) |
|---|---|---|---|
| 30 | ~1 | Fast test | ~50 |
| 100 | ~3 | Quick scan | ~150 |
| 300 | ~10 | Medium | ~500 |
| 500 | ~17 | Good coverage | ~1000 |
| 1000 | ~33 | Maximum | ~2000+ |
[]
= 300 # adjust as needed
Speed Settings
| Setup | concurrency | delay_ms | Speed |
|---|---|---|---|
| Safe (1 token) | 3 | 1000 | ~30/min |
| Normal (1 token) | 5 | 500 | ~60/min |
| Fast (3+ tokens) | 10 | 300 | ~150/min |
| Blazing (5+ tokens) | 20 | 100 | ~300/min |
Multiple Tokens (Different Accounts)
For maximum speed, use tokens from different GitHub accounts:
[]
= [
"ghp_from_account_1",
"ghp_from_account_2",
"ghp_from_account_3",
"ghp_from_account_4",
"ghp_from_account_5",
]
= 20
= 100
| Setup | Speed | Keys Found |
|---|---|---|
| 1 token, 1 account | 30/min | ~500/scan |
| 5 tokens, 5 accounts | 150/min | ~5000/scan |
| 10 tokens, 10 accounts | 300/min | ~10000/scan |
Project Structure
keyhunter/
โโโ Cargo.toml
โโโ config.toml.example
โโโ config.toml # Your config (git-ignored)
โโโ Dockerfile # Docker build
โโโ docker-compose.yml # Docker compose
โโโ .dockerignore
โโโ README.md
โโโ .gitignore
โโโ LICENSE
โโโ assets/
โ โโโ screenshot.png # Screenshot for README
โโโ results/ # Scan results saved here
โโโ src/
โ โโโ main.rs # CLI entry point
โ โโโ config.rs # Config parser
โ โโโ patterns.rs # 45+ provider patterns
โ โโโ github.rs # GitHub API client
โ โโโ scanner.rs # Core scanner
โ โโโ verifier.rs # Key verification (20+ providers)
โโโ tests/
โโโ config_test.rs # Configuration tests
โโโ filters_test.rs # False positive filter tests
โโโ patterns_test.rs # Regex pattern tests
Development
Prerequisites
Option A: Native (Rust)
- Rust 1.70+ (
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh)
Option B: Docker
- Docker 20.10+
Building
Native:
# Clone repository
# Build debug (faster compile)
# Build release (optimized)
Docker:
# Clone repository
# Build image
Running Tests
# Run all tests
# Run specific test file
# Run with output
Test Coverage:
patterns_test.rs- 34 tests for regex pattern matchingfilters_test.rs- 13 tests for false positive filteringconfig_test.rs- 12 tests for configuration parsing
Code Quality
# Format code
# Run linter
# Check without building
Running in Development
Native:
# Setup config
# Edit config.toml with your GitHub token
# Run debug build
# Run release build
Docker:
# Setup config
# Edit config.toml with your GitHub token
# Run with Docker
Adding New Providers
- Add pattern to
src/patterns.rs:
KeyPattern
- Add config toggle to
src/config.rs:
pub new_provider: bool,
-
Add to
enabled_providers()insrc/config.rs -
(Optional) Add verification in
src/verifier.rs -
Run tests:
cargo test
โ ๏ธ Disclaimer
This tool is for security research and educational purposes only.
- Only scan repositories you own or have permission to scan
- Report leaked keys responsibly to developers
- Never use found keys for unauthorized access
- Misuse may violate laws and GitHub Terms of Service
The authors are not responsible for misuse of this tool.
Ethical Use
This tool is for:
- โ Security researchers finding and reporting leaked keys
- โ Developers scanning their own repositories
- โ Organizations auditing their code
- โ Helping developers secure their secrets
NOT for:
- โ Stealing or misusing credentials
- โ Unauthorized access to systems
- โ Any malicious purposes
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-provider) - Make your changes
- Run tests (
cargo test) - Run linter (
cargo clippy) - Format code (
cargo fmt) - Commit changes (
git commit -m 'Add new provider') - Push to branch (
git push origin feature/new-provider) - Open a Pull Request
Ideas for contributions:
- Add new API key providers
- Improve regex patterns
- Add verification for more providers
- Documentation improvements
- Bug fixes
License
MIT License - see LICENSE for details.