RepoDx
Check your AI-built project before you push it. One command, zero dependencies, and nothing leaves your machine.
Coding agents such as Cursor, Claude Code, Lovable, Bolt and Replit ship apps fast.
They also paste API keys into source files, commit .env files, create
Supabase tables without Row Level Security and leave Firebase rules wide open.
In 2025, public GitHub commits leaked about 28.6 million new secrets, and leaked
AI-service keys grew 81% in one year
(GitGuardian, State of Secrets Sprawl 2026).
Bots find a leaked key within minutes.
RepoDx scans your project folder, gives it a score, and tells you in plain language how to fix each problem.
Installation
Install from PyPI with an isolated tool manager:
pipx install repodx
# or
uv tool install repodx
Run it once without installing anything (Python 3.9+ is the only requirement):
curl -sSL https://github.com/omerbek/repodx/releases/latest/download/repodx.py | python3 - .
Install the tagged GitHub version directly:
pipx install git+https://github.com/omerbek/repodx@v0.5.0
# or
uv tool install git+https://github.com/omerbek/repodx@v0.5.0
On Windows, you can also download repodx.py and run python repodx.py .
Usage
repodx # scan the current folder
repodx path/to/project # scan another folder
repodx --fix # apply safe fixes, then scan again
repodx --prompt # prompt to paste into Cursor, Claude Code or Lovable
repodx --install-hook # block commits with critical findings
repodx --json # machine-readable output
repodx --quiet # one-line score for scripts and hooks
repodx --format markdown # report for PR comments or CI summaries
repodx --badge # print a README badge with your score
repodx --fail-on critical # only fail on critical findings (default: warning)
Exit codes: 0 means nothing at or above --fail-on was found, 1 means
something was found, and 2 means the path is not a folder.
Fix it
repodx --fix applies the fixes that are always safe, then scans again:
- adds the missing lines to
.gitignore(.env,node_modules/,*.log, ...) and creates the file if it doesn't exist - creates a
.env.examplewith the variable names from your.envfiles and code, with the values left empty
It never deletes files, touches Git history or edits your code. For the rest it
prints what to do yourself, such as git rm -r --cached for files Git already
tracks and rotating leaked keys. Running it twice changes nothing.
repodx --prompt prints a prompt for your AI coding tool: every problem with
its location and fix, plus rules such as "never print or commit secret values"
and "run repodx . when you're done". Paste it into Cursor, Claude Code, Lovable
or Bolt.
repodx --install-hook installs a Git pre-commit hook, so a commit is
blocked while RepoDx finds a critical problem such as a leaked key or an
unignored .env file. A secret stopped before the commit never enters your Git
history. Skip the check once with git commit --no-verify. RepoDx doesn't
overwrite a pre-commit hook that it didn't install.
GitHub Action
# .github/workflows/repodx.yml
name: repodx
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: omerbek/repodx@v0.5.0
with:
fail-on: warning # critical, warning, info or never
The action writes the report to the job summary and fails the job when it finds problems.
pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/omerbek/repodx
rev: v0.5.0
hooks:
- id: repodx
Badge
Run repodx --badge and paste the output into your README:
[](https://github.com/omerbek/repodx)
What it checks
| Severity | Check |
|---|---|
| critical | API keys and tokens: OpenAI, Anthropic, OpenRouter, Perplexity, Replicate, Groq, Hugging Face, AWS, GitHub, GitLab, npm, PyPI, Stripe, Supabase secret keys, Shopify, DigitalOcean, Slack, SendGrid, Telegram bots, private keys |
| critical | Slack and Discord webhook URLs |
| critical / warning | Secret-looking variable names behind public prefixes that ship to the browser (NEXT_PUBLIC_OPENAI_API_KEY, VITE_STRIPE_SECRET_KEY, EXPO_PUBLIC_..._SERVICE_ROLE_KEY), even with an empty value |
| critical | Supabase service_role JWTs (the JWT is decoded to check its role; public anon keys are not reported) |
| critical | Database URLs with a real password (postgres://, mysql://, mongodb+srv://, redis:// ...), except local hosts and placeholders |
| critical | .env and .env.local files that are not ignored (other variants such as .env.production, and files with only NEXT_PUBLIC_/VITE_ variables, are warnings) |
| critical | Firebase firestore.rules, storage.rules or database.rules.json that let anyone write (public reads are reported as info) |
| critical / warning | Files over 100 MB (GitHub rejects them) and over 50 MB |
| warning | Google API keys (public if they are Firebase web keys, secret if they are Gemini, Maps or Cloud keys) |
| warning | Supabase migrations that create tables without enable row level security |
| warning | Committed junk: node_modules/, __pycache__/, virtualenvs, dist/, .next/, coverage/, .log, .tmp, .DS_Store |
| warning | Missing .gitignore or missing .env, node_modules/ and __pycache__/ entries |
| warning | Missing README or LICENSE |
| info | Code reads environment variables but there is no .env.example |
| info | README without Installation or Usage sections (English and Turkish headings are recognized) |
| info | AGENTS.md or CLAUDE.md over 300 lines (coding agents tend to ignore long instruction files) |
To keep false alarms rare, RepoDx:
- skips values that look like documentation placeholders (
AKIAIOSFODNN7EXAMPLE,[YOUR-PASSWORD],xoxb-0000...,-----BEGIN PRIVATE KEY-----\n...) and the public demo keys of the local Supabase CLI - reports secrets and
.envfiles in test and example folders as warnings, not critical - only expects
node_modules/in.gitignorewhen there is apackage.json, and__pycache__/when there are Python files
RepoDx reads your .gitignore, including ! re-include rules. Files that Git
would not commit are not reported, and ignored folders are not scanned. Found
secrets are masked in the output (sk-pro...l2).
The score starts at 100. Each critical finding subtracts 25, each warning 8 and each info 2, and each kind of problem counts at most three times. Grades: A ≥ 90, B ≥ 80, C ≥ 65, D ≥ 50, F below 50.
Tested on real projects
Before each release, RepoDx is run on large public repositories to catch false alarms. Results for 0.3.0:
| Repository | Files | Time | Critical | Result |
|---|---|---|---|---|
| vercel/ai-chatbot | 181 | 0.1 s | 0 | 100 (A) |
| langchain-ai/langchain | 3,165 | 2.3 s | 0 | 98 (A) |
| fastapi/fastapi | 3,139 | 1.6 s | 0 | 90 (A) |
| openai/openai-cookbook | 3,601 | 3.1 s | 0 | four data files over 50 MB |
| psf/requests | 128 | 0.2 s | 0 | test certificates' private keys (warnings) |
| supabase/supabase | 17,564 | 6.9 s | 0 | example tables without RLS, example .env files |
| vercel/next.js | 32,215 | 7.5 s | 0 | example .env files, test certificates |
| firebase/quickstart-js | 436 | 0.3 s | 1 | database.rules.json has ".write": true (real) |
The first version of these checks raised 136 critical alarms on the same repositories. Almost all of them were documentation placeholders and test fixtures, and the rules above were added to filter them out.
Silencing false positives
-
Add
repodx:ignorein a comment on the line to skip that line. -
Add a
.repodxignorefile (gitignore syntax) to skip whole paths, such as test fixtures:tests/fixtures/ docs/examples/*.md
What RepoDx does not do
- It scans the files in your folder, not your Git history. If a key was ever pushed, rotate it: deleting the file does not remove it from history. For history scans, use Gitleaks or TruffleHog.
- It does not connect to your live Supabase or Firebase project. The RLS and rules checks only read the files in your repo.
- It is a fast first check, not a full security audit.
Contributing
First-time contributors are very welcome. Each good first issue is a small, self-contained task, usually adding one secret provider with a test, and explains exactly which lines to change. Comment on an issue to claim it, then open a PR. See CONTRIBUTING.md.
Found a false alarm or a missed secret? Open an issue with the line (with the secret replaced).
Contributors
Thanks to everyone who has made RepoDx better:
Support
RepoDx is free and MIT licensed. If it saved you from a leaked key:
-
Star the repo, it helps other people find it.
-
Report false alarms and missed problems in issues.
-
Sponsor on GitHub: https://github.com/sponsors/omerbek
-
Donations are welcome at this Ethereum address (ETH or ERC-20 tokens on Ethereum mainnet):
0xb74e0A471bC60BB52067353C024e9bBA5a123F48
Development
RepoDx is a single Python file with no dependencies, so it is easy to read and
extend. Each check is a small function in repodx.py that returns findings.
The sample_repo/ folder is intentionally broken, and every credential in it
is fake. It is used by the tests and by the example above.
Run the test suite:
python3 -m unittest discover
Adding a check:
- Write a function that returns
make_finding(...)results. - Add its fix text to
FIXES. - Call it from
build_report. - Add a test in
tests/test_repodx.py.
Release files for repodx 0.5.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 | |
|---|---|---|---|
| repodx-0.5.0.tar.gz | 33.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| repodx-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.7 kB
Release files / repodx-0.5.0.tar.gz
| Download URL | repodx-0.5.0.tar.gz |
|---|---|
| Size | 33.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f26ba8bc6668b3ced456d907cb1df46eb62c4a119a56d7d72cf62c9dda78145f
|
|
BLAKE2b-256 checksum How to use checksums |
511c1fda4a98665bad252a0abf0c9b3735e301cbbbc6c6428dfea9450d280551
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / repodx-0.5.0-py3-none-any.whl
| Download URL | repodx-0.5.0-py3-none-any.whl |
|---|---|
| Size | 22.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
466386b4f32ef99e9948b7b77228bb89eff488b784d0a80c31be1b55ceb07a74
|
|
BLAKE2b-256 checksum How to use checksums |
0369cde3419133fc6b93ba19b422caca392a0d4b6873eaadd60451c24efd81d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log