Your AI agent can write code. It should not be able to quietly turn off your paywall and deploy it.
A read-only command that scans your repo in about a second and fails the build on twenty-two ways an AI agent quietly breaks production — across Supabase, Firebase and Stripe.
$ npx prodguard check ~/my-app ProdGuard · 80 files scanned · ~/my-app 🔴 CRITICAL Paid features are unlocked for everyone paywall-disabled Your paywall is hardcoded open. Every visitor gets the paid product for free, and your Stripe subscriptions stop meaning anything. src/pages/Dashboard.jsx:20 const locked = false → `locked` is pinned to `false` instead of being derived from the user's → subscription. src/pages/QuoteDetail.jsx:169 const locked = false → `locked` is pinned to `false` instead of being derived from the user's → subscription. Result: 2 critical ✗ Blocking. Fix these before shipping, or add an allow entry to .prodguardrc.json.
An audit of this tool found that an email-verification finding it used to report
here was a false positive — supabase/config.toml configures the local dev stack and ships
that setting disabled in every project, so it was removed. Settings that live in a hosted dashboard
rather than the repository are outside what any repo scanner can see.
What check does, locally, in under a second:
.env files in the directory you point it at, and nothing outside it. It does not follow symlinks.init, which writes a config file and a GitHub Action — and tells you what it wrote.Not ready to point it at your own code?
npx prodguard check --demo runs all twenty-two against a deliberately broken example app.
This takes about two minutes and installs nothing permanently.
node --versionIf you see a number like
v20.11.0, you're set. If it says
command not found, install Node from
nodejs.org — take the button on the left — then close Terminal and
reopen it.
npx prodguard check --demoIt will ask Ok to proceed? (y) the first time — press enter. This runs against a broken example app that lives inside the tool. Your files are not read at all.
cd and a space, then drag your project folder onto the Terminal window —
that pastes the path for you — and press enter. Then:
npx prodguard check
src/pages/Dashboard.jsx:20. Open that file, go to that line, and decide for yourself
whether it's a real problem. A finding is a prompt to look, not a verdict.
Nothing dangerous found? That means these twenty-two checks didn't
fire — not that your app is perfect.
npx prodguard initThis writes two small files into your project. Commit them, and from then on GitHub runs the check on every pull request — including the ones your AI agent opens — and blocks the merge if something critical shows up.
Stuck on any of this? Open an issue and say where you got lost — that's useful feedback, not a bother.
Every one of these is a way an AI agent has actually broken a real app. One of them exists because I nearly saved my own npm recovery codes into this repository.
| Severity | What it catches |
|---|---|
| Critical | Your paid features are unlocked for everyone
paywall-disabled |
| Critical | Anyone can POST a fake payment and unlock an account
stripe-webhook-unverified |
| Critical | Your admin database key can reach the browser
service-role-key-exposed |
| Critical | Row Level Security is off — users can read each other's rows
rls-disabled |
| Critical | A live Stripe or API key is sitting in your source tree
live-secret-committed |
| Critical | A recovery-codes or credentials file is sitting in the repo
credential-file-committed |
| High | A table was created and RLS was never turned on for it
rls-never-enabled |
| High | Accounts go live without proving they own the email
email-verification-disabled |
| Critical | Login tokens are read without checking the signature
jwt-not-verified |
| Critical | Firebase rules allow anyone to read or write
firebase-rules-open |
| High | Any website can call your API with your users' cookies
cors-wildcard-credentials |
| High | A migration drops or empties a table
destructive-migration |
| Critical | A SECURITY DEFINER function is callable by anonymous users, so it runs past RLS
security-definer-anon-executable |
| High | A view in public has no security_invoker, so it reads past RLS
security-definer-view |
| Medium | A SECURITY DEFINER function has no fixed search_path
security-definer-search-path |
| Critical | Insert, update or delete granted to anon — RLS never touched, access just widened
anon-write-grant |
| Critical | A USING (true) policy added beside a real one, which silently wins
duplicate-permissive-policy |
| High | GRANT ALL replaces your column-level grants and adds TRUNCATE
grant-all-on-table |
| High | A policy with no TO clause whose predicate ignores the caller, so anon gets rows
policy-missing-to-clause |
| Medium | A policy filtering on a column no migration creates, usually the wake of a rename
policy-references-missing-column |
| Critical | Every table in a schema granted at once to a role a client can reach
grant-schema-wide |
| Critical | A policy that scopes reads but leaves WITH CHECK unconditional, so writes are open
policy-write-check-open |
$ npx prodguard init ✓ wrote .prodguardrc.json ✓ wrote .github/workflows/prodguard.yml
That workflow runs on every pull request — including the ones your agent opens. Dangerous changes stop merging instead of stopping your revenue.
Want it earlier, before a commit even exists:
# .husky/pre-commit
npx prodguard check
The agent that turns these controls off can also be the one that catches it. ProdGuard ships a Claude Code skill, so Claude runs the scan, reads the findings and proposes the fix before you ship.
$ mkdir -p .claude/skills/prodguard
$ curl -o .claude/skills/prodguard/SKILL.md \
https://raw.githubusercontent.com/Felix0731/prodguard/main/skill/SKILL.md
The skill spells out what ProdGuard does not cover as plainly as what it does, so a clean run never gets reported back to you as “your app is secure”.
Every finding is written so that someone who can build an app can act on it. Not CWE-862: Missing Authorization — instead: “Row Level Security is off — any logged-in user can read and modify every other user's rows.”
The people breaking production with agents right now are frequently not senior engineers. A warning they can't decode is a warning they'll skip.