Secret scanner for the AI coding era — catches leaked API keys before they ship.
Project description
keyburn
Secret scanner built for the AI coding era.
Cursor, Copilot, and Lovable write code fast. Sometimes too fast — hardcoded API keys, database URLs, and JWT secrets end up committed before anyone notices. Keyburn catches them before they ship.
- 57 detection patterns — AWS, OpenAI, Anthropic, Stripe, Supabase, GitHub, Slack, and more
- Shannon entropy analysis — catches secrets that don't match a known pattern
- Actionable remediation hints — tells you exactly how to fix each finding, not just that something's wrong
- Provider-aware risk intelligence — each finding includes provider + risk score + exposure signals
- Rotation runbook stubs — generate one-command incident response plans for AWS/GitHub/Stripe
- Framework-aware — knows that
NEXT_PUBLIC_SECRET_KEYis exposed to the browser, that Supabaseservice_rolekeys bypass RLS, etc. - Zero noise escape hatches —
# keyburn:ignore, allowlists, baselines, per-path excludes - CI-native — text/JSON/SARIF output, GitHub code scanning integration, fail threshold per severity
Install
pip install keyburn
# or, zero-install:
pipx run keyburn scan .
Quickstart
# Scan current directory
keyburn scan .
# Scan and fail CI on any high-severity finding
keyburn scan . --fail-on high
# Only scan added lines changed in this PR
keyburn scan . --diff origin/main
# Only scan added lines in staged files (pre-commit)
keyburn scan . --pre-commit
# Output SARIF for GitHub code scanning
keyburn scan . --format sarif --out keyburn.sarif
Verify likely-live keys
keyburn verify checks whether a detected token is still active for selected providers.
Supported providers (current): openai, anthropic, groq, github, stripe.
# safest path: load from env var (avoid shell history leaks)
keyburn verify --from-env OPENAI_API_KEY --provider openai
# auto-infer provider from token format
keyburn verify --from-env GITHUB_TOKEN --provider auto
# verify Anthropic/Groq keys explicitly
keyburn verify --from-env ANTHROPIC_API_KEY --provider anthropic
keyburn verify --from-env GROQ_API_KEY --provider groq
# fail CI if token appears active
keyburn verify --from-env STRIPE_SECRET_KEY --provider stripe --fail-on-valid
Rotation Stubs
keyburn rotate prints provider-specific rotation runbooks for fast incident response.
# Build an AWS key rotation plan
keyburn rotate --provider aws --resource AKIA1234567890ABCDEF
# Build a GitHub token rotation plan
keyburn rotate --provider github --resource leaked-pat
# Build a Stripe key rotation plan (supports JSON output)
keyburn rotate --provider stripe --format json
GitHub Action
Add this to any workflow — it scans on every push/PR and uploads findings to GitHub code scanning:
- name: Scan for secrets
uses: safouanb/keyburn@v0
Or with options:
- name: Scan for secrets
uses: safouanb/keyburn@v0
with:
fail_on: high # low | medium | high (default: high)
format: sarif # text | json | sarif (default: sarif)
upload_sarif: "true" # upload to GitHub code scanning (default: true)
comment_pr: "true" # sticky PR comment with risk + playbooks (default: false)
Full workflow example:
name: Secret scan
on: [push, pull_request]
jobs:
secrets:
runs-on: ubuntu-latest
permissions:
security-events: write # required for SARIF upload
pull-requests: write # required if comment_pr=true
steps:
- uses: actions/checkout@v4
- uses: safouanb/keyburn@v0
with:
fail_on: high
comment_pr: "true"
Pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/safouanb/keyburn
rev: v0.1.9
hooks:
- id: keyburn
Or use the CLI directly in a git hook:
# .git/hooks/pre-commit
#!/bin/sh
keyburn scan . --pre-commit --fail-on high
Suppressing false positives
Inline, for a single line:
EXAMPLE_KEY = "not_a_real_secret_for_docs" # keyburn:ignore
Allowlist by regex in keyburn.toml:
[allowlist]
regex = [
"^sk_test_", # all Stripe test keys
"^EXAMPLE_KEY_", # placeholder values in docs
]
Baseline — accept current state, catch new ones:
# Run once to write the baseline
keyburn scan . --baseline baseline.json --update-baseline
# Future scans only alert on NEW findings
keyburn scan . --baseline baseline.json --fail-on high
Skip files or directories:
[scan]
exclude_paths = ["tests/fixtures/**", "docs/examples/**"]
exclude_dirs = [".venv", "node_modules"]
Disable specific rules:
[scan]
disable_rules = ["stripe-secret-test", "entropy"]
Configuration (keyburn.toml)
Drop a keyburn.toml in your repo root (see keyburn.toml.example):
[scan]
max_file_size_bytes = 2097152
exclude_dirs = [".venv", "node_modules", "dist"]
exclude_paths = ["tests/fixtures/**"]
disable_rules = []
respect_gitignore = true # skip files in .gitignore (default: true)
[allowlist]
regex = []
What it detects
| Category | Providers |
|---|---|
| AI APIs | OpenAI, Anthropic, Groq, HuggingFace, Replicate, Cohere |
| Cloud | AWS (key + secret + session), GCP, Firebase |
| Payments | Stripe (live + test + restricted) |
| Auth | GitHub PATs (classic + fine-grained), OAuth tokens, Clerk, Auth0 |
| Comms | Slack (tokens + webhooks), Twilio, SendGrid, Mailgun, Discord, Telegram |
| Database | PostgreSQL, MySQL, MongoDB, Redis (connection strings) |
| Infra | Heroku, Vercel, Netlify, Doppler, Sentry |
| E-commerce | Shopify |
| Packages | npm, PyPI tokens |
| Framework | NEXT_PUBLIC_ secrets, Supabase service role vs anon key |
| Generic | Hardcoded passwords, JWT secrets, PEM keys, .env pasted into source |
| Entropy | High-entropy strings assigned to secret-looking variables |
Output formats
Text (default) — rich panels with remediation hints per finding:
╭─ HIGH Stripe Secret Key (live) ────────────────────────────────╮
│ File: src/payments.js:12:20 │
│ Rule: stripe-secret-live │
│ Match: sk_l****************************1234 │
│ │
│ How to fix: This is a LIVE Stripe key — it can charge real │
│ cards. Roll it immediately at dashboard.stripe.com/apikeys. │
│ Use STRIPE_SECRET_KEY env var instead. │
╰──────────────────────────────────────────────────────────────────╯
JSON — machine-readable with full finding metadata:
keyburn scan . --format json | jq '.summary'
SARIF — GitHub code scanning compatible:
keyburn scan . --format sarif --out keyburn.sarif
Git history scanning
Scan the last N commits for secrets that were added then "deleted":
keyburn scan --history 50 # last 50 commits
keyburn scan --history all # full history (slow on large repos)
Precision benchmark
Track scanner noise over time against real OSS repositories:
python scripts/benchmark_precision.py
Results are written to:
benchmarks/results/latest.jsonbenchmarks/results/latest.md
CI can run this weekly via .github/workflows/precision-benchmark.yml.
Adoption loop
Track external adoption/noise metrics across real open-source repositories:
python scripts/adoption_loop.py
Results are written to:
adoption/results/latest.jsonadoption/results/latest.md
CI can run this weekly via .github/workflows/adoption-loop.yml.
Known limitations
- Key verification currently supports OpenAI, Anthropic, Groq, GitHub, and Stripe.
- Verification is a live HTTP check and can return
unknownduring rate limits/outages. - A
validcheck means "accepted by provider now"; it does not measure scope or blast radius. keyburn rotatecurrently emits manual/CLI runbook stubs and does not auto-execute rotation..gitignorematching is intentionally lightweight and may differ from full git pathspec semantics.
Open-core
The scanner and all detection rules are open-source (Apache-2.0). Dashboards, Slack/email alerting, and one-click credential rotation live in a separate hosted product.
Contributing
See CONTRIBUTING.md. New detectors: open an issue with the provider, a redacted example, expected severity, and known false positives.
License
Apache-2.0. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keyburn-0.1.9.tar.gz.
File metadata
- Download URL: keyburn-0.1.9.tar.gz
- Upload date:
- Size: 44.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ff77a6317ee4404f254e5b70e19503e9db5626ccfa6aa319956b6459b1b0416
|
|
| MD5 |
6d57fd103517d6563b3cacd4aa446218
|
|
| BLAKE2b-256 |
566ebec1e10d3004b8ee695141394029f75f50e37d3e17ee188e3155cec24f7f
|
Provenance
The following attestation bundles were made for keyburn-0.1.9.tar.gz:
Publisher:
release.yml on safouanb/keyburn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keyburn-0.1.9.tar.gz -
Subject digest:
0ff77a6317ee4404f254e5b70e19503e9db5626ccfa6aa319956b6459b1b0416 - Sigstore transparency entry: 976431768
- Sigstore integration time:
-
Permalink:
safouanb/keyburn@032d2d135c8e0679a9075910c5cad721d63178e5 -
Branch / Tag:
refs/tags/v0.1.9 - Owner: https://github.com/safouanb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@032d2d135c8e0679a9075910c5cad721d63178e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file keyburn-0.1.9-py3-none-any.whl.
File metadata
- Download URL: keyburn-0.1.9-py3-none-any.whl
- Upload date:
- Size: 37.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58c9589617195f995e99e3edb2973bdbd3805dbe916ca095cd149049494e6226
|
|
| MD5 |
fe9c95ca83ebffccef3c9d6acec04aca
|
|
| BLAKE2b-256 |
107779eb26084c27bd06102688dc721bf196684c67952696c2ea4f5778dda9a7
|
Provenance
The following attestation bundles were made for keyburn-0.1.9-py3-none-any.whl:
Publisher:
release.yml on safouanb/keyburn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keyburn-0.1.9-py3-none-any.whl -
Subject digest:
58c9589617195f995e99e3edb2973bdbd3805dbe916ca095cd149049494e6226 - Sigstore transparency entry: 976431773
- Sigstore integration time:
-
Permalink:
safouanb/keyburn@032d2d135c8e0679a9075910c5cad721d63178e5 -
Branch / Tag:
refs/tags/v0.1.9 - Owner: https://github.com/safouanb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@032d2d135c8e0679a9075910c5cad721d63178e5 -
Trigger Event:
push
-
Statement type: