
CLI scanner that detects leaked API keys, tokens, and credentials in source trees and deployed web apps, with Supabase/Firebase misconfiguration checks and SARIF output.
Find what your vibe-coded app is leaking — before someone else does.
AI app builders (Lovable, Bolt, Cursor, v0, …) ship fast, and often ship with a
database wide open or a secret key inside the JavaScript bundle. keydra
looks at your deployed app the same way an outsider would, or at your
source tree before you deploy, and tells you what is exposed, with a
copy-paste fix.
[!IMPORTANT] keydra is primarily designed to run as a standalone CLI tool. Running keydra as a publicly accessible service may expose sensitive data and introduce security risks. Use it with caution and implement appropriate security controls.
$ keydra scan https://my-app.example.com
█▄
▄▄ ██ ▄
██ ▄█▀ ▄█▀█▄ ██ ██ ▄████ ████▄▄▀▀█▄
████ ██▄█▀ ██▄██ ██ ██ ██ ▄█▀██
▄██ ▀█▄▄▀█▄▄▄▄▄▀██▀▄█▀███▄█▀ ▄▀█▄██
██ v1.0.0
▀▀▀
Keydra — find what your vibe-coded app is leaking.
keydra: only scan apps you own or have permission to test.
url https://my-app.example.com
2 pages · 14 files scanned · 2.1s
1 [Supabase] Supabase table "profiles" is publicly readable
│ The table can be read with the public anon key. ...
│ evidence GET /rest/v1/profiles → 206, rows visible to anonymous role: 1204
│ fix alter table public.profiles enable row level security; …
1. Install Go. You need Go 1.27 or newer (go version to check; download from
https://go.dev/dl). With Go 1.21+ the right toolchain is fetched automatically
based on go.mod.
2. Get the code and build it.
unzip keydra.zip && cd keydra # or: git clone <your repo> && cd keydra
go build -o bin/keydra ./cmd/keydra # or: make build
Windows (PowerShell): go build -o bin\keydra.exe ./cmd/keydra
You do not need to rename the module to build locally. Replace
github.com/drau6/keydra with your own path only when you publish the repo
(or if you want go install github.com/<you>/keydra/cmd/keydra@latest to work).
3. Run your first scan.
# source code, before you deploy: safe, no network
./bin/keydra scan --repo .
# a deployed app you own (or have written permission to test)
./bin/keydra scan https://my-app.example.com
# also follow internal links, because secrets often hide on /admin or /dashboard
./bin/keydra scan https://my-app.example.com --depth 2
# see every check Keydra performs
./bin/keydra rules
4. Optional: install it on your PATH.
go install ./cmd/keydra # installs to $(go env GOPATH)/bin
keydra version
5. Optional: run the tests. go test ./... (or make test).
Notes: colors turn on automatically in a terminal. On legacy Windows cmd.exe
you may see raw escape codes; use Windows Terminal/PowerShell or --no-color.
The large banner is skipped when output is piped, when the terminal is narrower
than the banner (COLUMNS), or with --no-banner.
go install github.com/drau6/keydra/cmd/keydra@latest
(after you have replaced yourname and pushed the repo), or make build and use
bin/keydra.
keydra scan <url> [flags] # scan a deployed app
keydra scan --repo <dir> [flags] # scan source before you deploy
keydra scan --list <file> [flags] # scan every URL in the file, one per line (max 50)
keydra rules # list every check
keydra <url> # shortcut for scan
--repo <dir> scan a local source tree instead of a URL (no network)
--list <file> scan a list of URLs, one per line (# comments and blank lines ignored, max 50)
--format <fmt> text | json | sarif (default text); --json is a shortcut
--no-banner one-line title instead of the ASCII-art banner
--color <mode> auto|always|never (honors NO_COLOR and FORCE_COLOR; --no-color also works)
--no-probe static analysis only, never contact discovered backends
--validate opt-in: ask each provider (one read-only request) whether a detected secret is still active
--fail-on <sev> exit 1 at/above severity: info|low|medium|high|critical|never (default high)
--depth N page levels to crawl in URL mode: 1 = only the given page (default),
2 = also its internal links, up to 5
--max-pages N maximum HTML pages to fetch in URL mode (default 20, max 200)
--sitemap also scan pages listed in /sitemap.xml
--max-files N JS files to download in URL mode (default 40)
--third-party also scan scripts hosted on other origins
--timeout 15s per-request timeout
-v show full fix snippets
Exit codes: 0 clean, 1 findings at/above --fail-on, 2 error. With
--list, 2 also means "at least one target failed to scan" (unless findings
already forced exit 1).
A repo scan of a small vibe-coded app (--no-color --no-banner; on an
interactive terminal the banner is ASCII art and the │ gutter is colored by
severity — red critical, orange high, blue low):
KEYDRA v1.0.0
keydra: only scan apps you own or have permission to test.
repo my-app
3 files scanned · 1ms
1 [Supabase] Supabase service/secret key exposed in client code
│ This key bypasses Row Level Security. Whoever holds it has full read/write access to the whole database.
│ evidence eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWowMTIzNDU2Nzg5Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0OTgxODI0OSwiZXhwIjoyMDY1Mzk0MjQ5fQ.AAAAAAAAbbbbbbbbCCCCCCCCddddddddEEEEEEEE
│ fix Rotate the key in Supabase → Project Settings → API now, remove it from the frontend and use it only from server-side code.
2 [Repository] .env is not covered by .gitignore
│ Environment files normally hold server secrets. If this file is committed, every secret in it is in your git history.
│ where .env
│ fix Add ".env*" and "!.env.example" to .gitignore. If it was already committed: `git rm --cached .env`, then rotate every key inside and purge history.
3 [Secrets] Possible unnamed secret (high-entropy string) exposed in client code
│ This value ships to every visitor's browser and can be copied by anyone.
│ evidence eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWowMTIzNDU2Nzg5Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0OTgxODI0OSwiZXhwIjoyMDY1Mzk0MjQ5fQ.AAAAAAAAbbbbbbbbCCCCCCCCddddddddEEEEEEEE
│ where lib/api.js
│ fix Keydra found a long, random-looking string that matches no known key format. Check whether it is a credential: if so, rotate it and move it server-side. Build artifacts such as hashes or encoded assets can be ignored.
note: Supabase configuration found in source; run `keydra scan <deployed-url>` to test the live backend
Every finding shows the matched value in full (evidence), where it was found, and a copy-paste fix — so a scan report is all you need to start remediation. Values above are examples, not real keys.
By default only the page you give is scanned (plus its scripts, lazy chunks and
source maps). Use --depth to follow internal links, and --sitemap to add the
pages a site lists in /sitemap.xml:
keydra scan https://my-app.example.com --depth 3 --max-pages 40
keydra scan https://my-app.example.com --sitemap