100% freeOpen source · MIT licensed · ★ Star on GitHub

Find the API keys your website gives away.

Anyone can press Inspect on your site and copy the keys inside your JavaScript. LeakLock shows you exactly what they'd find, and how to fix it, in about ten seconds.

https://
✓Free forever, no sign-up ✓Keys always masked ✓Nothing stored

Works with apps built on

  • Lovable
  • Bolt
  • v0
  • Cursor
  • Replit
  • Next.js
  • Vite
  • Vercel
  • Netlify
  • Supabase
Research · October 2026

We scanned 978 live apps.

Public apps on Lovable, Bolt, Vercel, Netlify and Cloudflare Pages, linked from open GitHub projects. We read only what any visitor's browser downloads: 9,698 files.

1 in 26

apps shipped at least one secret key to every visitor's browser.

37 of 978 apps · public-by-design keys like Supabase anon and Firebase web excluded
Telegram bot tokens17
AI API keys9
GitHub tokens6
Found only by usage2
Discord webhooks2
6apps leaked a critical key
9apps exposed Groq, Gemini, OpenAI or OpenRouter keys
8.8%served public source maps

Counts are apps. Results are aggregate only: no app is named, and every key was masked during the scan.

Why LeakLock

Built for how apps really leak keys today.

AI builders move fast and put API calls right in the frontend. LeakLock checks the one place that matters: what actually ships to the browser.

Finds keys other scanners miss

Pattern scanners only know formats they've been taught. LeakLock also catches any key by how your code uses it, even a plain random string, and names the API it calls.

Authorization: Bearerx-api-key?key=minified vars

Sees what visitors see

HTML, every bundle, lazy-loaded chunks and public source maps.

A fix, not a lecture

Plain steps and a prompt to paste into Lovable, Bolt or Cursor.

Stops leaks before they ship

Run it in CI with the GitHub Action. The build fails when a secret is about to go live, and the run summary shows every finding.

npx leaklockGitHub ActionJSON output
30+providers by key format, plus any API by usage
~10sto scan a typical app
0dependencies. Read it in an afternoon.
100%of keys masked. Nothing is ever stored.
How it works

What a visitor sees.
What LeakLock tells you.

Your build bundles your code into JavaScript files every browser downloads. If a key is in your code, it's in those files, minified but intact.

Sources · assets/index-4f2a9c.js
const e="d41f8b2c09e7a51f3b6d8e4a7c2f0a07",
      t="https://api.kie.ai/v1";
async function r(a){
  const s=await fetch(`${t}/jobs`,{
    method:"POST",
    headers:{Authorization:`Bearer ${e}`},
    body:JSON.stringify({prompt:a})
  });
  return s.json()
}
const o=createClient(
  "https://xyzcompany.supabase.co",
  "eyJhbGciOiJIUzI1NiIs…"
);
LeakLock · yourapp.com
Secretkie.ai API keyd41f…0a07

Sent as a Bearer token to api.kie.ai, traced through the minified variable e. Anyone can call that API as you.

FixMove this call into a server function and keep the key there. A copy-paste prompt is included.
SafeSupabase anon keyeyJh…c3Rw

Public by design. Your data is protected by Row Level Security, not by hiding this.

What anyone sees in Inspect → Sources

What LeakLock reports

The blind spot

Not every key starts with sk-

Many AI, image and voice APIs hand out plain random strings. Scanners that match known formats let them straight through. LeakLock watches how a value is used.

01Authorization: Bearer …

A value sent as a bearer token

02"x-api-key": …

A value in any API-key header

03?key=…

A value passed as a key in a URL

Pattern-based scanner$ scan dist/
index.html
assets/index-4f2a9c.js
assets/vendor-91bc.js
checked every known key format

✓ no secrets found
  the kie.ai key has no known format
LeakLock$ npx leaklock scan dist/
SECRET  kie.ai API key  d41f…0a07
        sent as a Bearer token to api.kie.ai
        in assets/index-4f2a9c.js
SAFE    Supabase anon key  eyJh…c3Rw

1 secret · 1 safe (public by design)
Compare

Gitleaks checks your repo.
LeakLock checks what you ship.

A key can be clean in git and still land in your bundle through a VITE_ or NEXT_PUBLIC_ variable. Use both.

LeakLockGitleaksTruffleHog
ScansYour live site or build outputGit history and filesGit, files, S3, Slack and more
Keys with a known format✓30+ web and AI providers✓Hundreds✓800+
Keys with no known format✓Found by how they're used–Entropy rules only–No
Public-by-design keys✓Marked safe, with the reason–Often flagged–Often flagged
Fix for each finding✓Steps and an AI-builder prompt–No–No
Checks if a key is still livePlanned–No✓Yes
LicenseMITMITAGPL-3.0

Gitleaks and TruffleHog are excellent at what they do. LeakLock covers a different place keys leak.

The fix

Every finding comes with the fix.

Not just "rotate your key." You get the steps, and a prompt for the tool that built your app.

  1. 1Move the call to a serverA small function in Supabase, Vercel or Netlify makes the request instead of the browser.
  2. 2Keep the key thereStored as a server secret, never in a VITE_ or NEXT_PUBLIC_ variable.
  3. 3Scan againConfirm the key is gone from what you ship.
  4. 4Consider rotating itIf the key was public, someone may already have a copy.
Paste into Lovable, Bolt, Cursor or v0My app exposes a kie.ai API key in the browser bundle (found in assets/index-4f2a9c.js, sent to api.kie.ai). Anyone can copy it. Fix this without changing how the app behaves: 1. Create a server-side function (use a Supabase Edge Function if this project uses Supabase, otherwise a serverless function on our host) that makes the same kie.ai request, reading the key from a secret named KIE_AI_API_KEY. 2. Replace the browser's direct call with a call to that function, passing the same inputs and returning the same response shape. 3. Remove the key from all frontend code, .env files with VITE_ or NEXT_PUBLIC_ prefixes, and constants. 4. Only allow requests from our own site and add a basic rate limit. 5. Do not change any UI, routes or other logic. List every file you changed.
For developers

Catch it before it ships.

Run it on a build folder, a preview URL or production. Fail the pull request when a secret is about to go live.

✓Zero dependencies, MIT licensed, one small package.
✓Masked output, plus JSON for your own scripts.
✓Runs locally. Your keys never leave your machine.
# a live site, any host
npx leaklock scan yourapp.com

# your build folder, with fixes
npx leaklock scan dist/ --fix

# exit 1 if a secret ships
npx leaklock scan dist/ --fail-on=secret
# .github/workflows/leaklock.yml
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - uses: sgroy10/leaklock@v1
        with:
          target: dist
          fail-on: secret
import { scanUrl } from 'leaklock';

const report = await scanUrl('yourapp.com');
console.log(report.summary);
// { critical: 0, secret: 1, review: 0, safe: 1 }

for (const f of report.findings) {
  console.log(f.severity, f.provider, f.masked);
}
Pricing

Free. Open source. Forever.

No account, no sign-up, no paid tier for scanning. LeakLock is MIT licensed, so you can read every line, run it anywhere and change it.

★Star LeakLock on GitHub
✓Unlimited scans in the browser
✓CLI and GitHub Action, free for any use
✓Fix prompts for Lovable, Bolt, Cursor and v0
✓Zero dependencies, MIT licensed
FAQ

Questions, answered.

Is it safe to paste my URL here?

LeakLock only downloads the public files any browser would load from your site. Keys are masked before they leave the server, nothing is stored, and private or internal addresses are refused. Prefer your own machine? Run npx leaklock scan yourapp.com.

It found my Supabase anon key. Is that a problem?

No. The anon key is meant to be public. What protects your data is Row Level Security on every table. The service_role key is different: it bypasses all security, and LeakLock marks it critical.

Can't I just hide the key in the frontend?

No. Obfuscating, splitting or encrypting a key in the browser doesn't work, because the real key appears in the Network tab the moment it's sent. The only fix is that the key never reaches the browser.

Do I have to create a new key?

Moving the call to a server stops new copies. A key that was already public may have been copied, and rotating it is the only way to cut that off. LeakLock tells you the risk; the decision is yours.

"No keys found." Am I safe?

It's good news, not a guarantee. Keys hidden in unusual ways can be missed, and LeakLock doesn't test your database rules or server code.

Is it really free?

Yes. The web checker, CLI and GitHub Action are free with no account. LeakLock is MIT licensed open source.

Can I scan someone else's site?

Only scan sites you own or have permission to test. If you find a leak on someone else's site, tell them privately.

Scan your site before
someone else does.

About ten seconds. Free, and nothing is stored.

https://

Useful? Star LeakLock on GitHub so more builders see it.