Methodology & privacy
How LeakCheck works
LeakCheck scans the text you paste for things that look like API keys, tokens, and private keys — and it does the whole job inside your browser. This page explains exactly how that detection works, what it can and can’t see, and what to do the moment you find a real leak.
- Privacy guarantee
- What we detect
- How detection works
- Masking
- Not a security audit
- I found a leaked key
- Roadmap
The privacy guarantee: nothing leaves your browser
This is the part that matters most, so we’ll be blunt about it: LeakCheck has no backend. When you paste code, a .env file, or config into the scanner, every byte stays on your machine. The scanning happens in JavaScript, locally, in the same tab you’re looking at.
Concretely, that means:
- No network requests with your content. Your code and secrets are never uploaded, POSTed, beaconed, or sent to any server — ours or anyone else’s.
- No logging or storage. We don’t keep what you paste. It isn’t written to a database, a log file, local storage, or analytics. Close or reload the tab and it’s gone.
- It works offline. Load the page once, disconnect from the internet, and the scanner still runs. That’s the simplest proof there’s nothing to upload to.
We built it this way on purpose. A tool that asks you to paste your secrets somewhere, and then ships those secrets to a server, is a worse problem than the one it claims to solve. LeakCheck never puts you in that position.
What we detect
LeakCheck ships with a library of named patterns for common providers, plus a general high-entropy catch-all for credentials that don’t match a known format. Severity reflects how dangerous an exposure typically is — a live cloud or payment key is a Fail, a lower-blast-radius or context-dependent token is a Warn, and informational matches are Pass.
| Provider / type | Example format | Severity |
|---|---|---|
| AWS access key ID | AKIA0123456789ABCDEF | Fail |
| AWS secret access key | 40-char base64-ish secret | Fail |
| Stripe live secret key | sk_live_… | Fail |
| Private key block (RSA/EC/PGP) | -----BEGIN … PRIVATE KEY----- | Fail |
| GitHub token | ghp_… / github_pat_… | Fail |
| OpenAI / Anthropic API key | sk-… / sk-ant-… | Fail |
| Google API key | AIza… | Warn |
| Slack token | xoxb-… / xoxp-… | Warn |
| Stripe test secret key | sk_test_… | Warn |
| JSON Web Token (JWT) | eyJ….eyJ….<sig> | Warn |
Generic SECRET= / PASSWORD= assignment | API_SECRET="…" | Warn |
| High-entropy string (unmatched) | random 32+ char blob | Pass |
The exact pattern set evolves; treat this table as representative, not exhaustive. Severities are defaults and reflect typical blast radius, not your specific setup.
How detection works
Detection runs in two complementary passes:
1. Named regular-expression patterns
Most cloud providers give their credentials a recognizable shape — a fixed prefix, a known length, a specific alphabet. LeakCheck carries a curated set of regular expressions for those formats (for example, AKIA followed by 16 base-32 characters for AWS, or sk_live_ for Stripe). When the text matches a named pattern, the finding is precise: we can tell you which provider it belongs to and assign a meaningful severity.
2. Entropy heuristics
Plenty of secrets don’t follow a public format — bespoke session tokens, hand-rolled API keys, raw passwords. For those, LeakCheck measures Shannon entropy: a score of how random and unpredictable a string is. Ordinary English words and code identifiers have low entropy; a genuinely random 32-character credential has high entropy. Long, high-entropy strings — especially ones sitting next to a tell like key, token, secret, or = — get surfaced even when no named pattern matches.
The two passes back each other up: named patterns give you accuracy on the providers we know, and entropy gives you coverage on the ones we don’t.
How matches are masked
When LeakCheck shows you a finding, it does not print the full secret back onto the screen. Each match is masked — typically the leading few characters of the prefix are shown for identification and the rest is replaced with dots (for example, sk_live_4eC•••••••••••••••••••). This keeps the results readable and identifiable while reducing the chance of shoulder-surfing, an accidental screenshot, or a copied screen-share leaking the very thing you’re trying to protect. The unmasked value never leaves your browser regardless, but masking means it isn’t casually visible even to you.
This is heuristic detection — not a security audit
Like every pattern-based scanner, LeakCheck can produce both kinds of error:
- False negatives. Secrets in formats we don’t recognize, encoded or split across lines, or below the entropy threshold can slip past unflagged.
- False positives. Random-looking but harmless strings — hashes, UUIDs, test fixtures, example keys — can be flagged when they aren’t real credentials.
Use LeakCheck as a quick first pass before you commit or share code, not as the final word on whether your project is safe. A real audit considers your architecture, dependencies, access controls, and threat model — none of which a text scanner can see. If you need that level of assurance, talk to Copper Bay Labs.
I found a leaked key — now what?
If a real credential has been exposed, assume the worst and act fast. Treat the order below as a checklist:
- Rotate it immediately. Go to the provider’s dashboard and revoke or regenerate the key right now. Rotation is the only action that actually stops abuse — deleting it from your code does not.
- Remove it from your code. Take the hard-coded value out of every source file, config, and notebook where it appears.
- Move it to an environment variable or secret manager. Load secrets at runtime from
.env(git-ignored) for local work, and from a real secret manager — AWS Secrets Manager, GCP Secret Manager, Vault, GitHub Actions secrets, your platform’s vault — for anything deployed. - Scrub it from git history. A removed-then-committed secret still lives in every prior commit. Rewrite history with
git filter-repoor BFG Repo-Cleaner, then force-push and have collaborators re-clone. Remember any forks and PRs may still carry it. - Treat the old key as compromised forever. Once a secret has been public — even briefly, even in a private repo that was shared — assume it’s in someone’s scrape. The exposed value can never be trusted again. The rotated key is your real key; the old one is dead.
On the roadmap
Pre-commit & CI ruleset pack. The best place to catch a secret is before it’s ever committed. We’re packaging LeakCheck’s patterns into a drop-in ruleset for pre-commit hooks and CI pipelines, so the same detection that runs here can block secrets at the door of your repo — automatically, on every push. Stay tuned.