ProdGuard

v0.10.0
0 dependencies · Node ≥18
MIT

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.

What it actually prints

Run against a real project

$ 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.
Complete, unedited output from a real project; only the path is anonymised. Exit code 1, so CI stops.
Blocking · exit 1

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:

$npx prodguard check

Not ready to point it at your own code? npx prodguard check --demo runs all twenty-two against a deliberately broken example app.

Getting started

If you have never run a terminal command

This takes about two minutes and installs nothing permanently.

  1. Check you have Node. Open Terminal (on a Mac press ⌘Space, type terminal, hit enter; on Windows open PowerShell from the Start menu). Paste this and press enter:
    node --version
    If 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.
  2. See what it does, without touching your code.
    npx prodguard check --demo
    It 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.
  3. Point it at your own project. Type 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
  4. Read what comes back. Every finding names the file and the line number, like 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.
  5. Optional: make it run automatically.
    npx prodguard init
    This 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.

Twenty-two checks

Only things that cost money or leak data

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.

SeverityWhat 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
Put it in front of the agent

One command wires it into CI

$ 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
Inside the agent

Let Claude run the check itself

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”.

Reports for humans

No CWE numbers

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.

Honest limits

What it is not