For engineers

You approve the change. Here is everything you need to say yes.

Each fix is a migration, re-tested in a rebuilt copy of the database as an anonymous visitor, a signed-in stranger and the owner. You get the SQL, the before-and-after counts, a risk note and a signed receipt. Nothing changes until you apply it.

The real fix from our demo app, 9 Nov 2026.

What you review

Evidence, in the formats you already use.

01SQL

A migration, not advice

A timestamped file for supabase/migrations, with comments on what changed and why. Download it, or commit it on GitHub.

02Proof

Counts for each identity

Rows read before and after, as anon, a signed-in stranger and the owner, on a database rebuilt from your migrations.

03Record

A signed receipt

Ed25519-signed: the result, the fix’s hash and every decision your team made. Verifiable by anyone with the public key.

How the proof runs

The exact identities, simulated inside a disposable database.

The lab applies your migrations to a local Postgres with Supabase’s roles, auth.uid() and default grants, seeds fake rows for two users, then sets the role and JWT claims for each identity.

  • Never connects to your project; we never need a password or service key
  • The smallest model writes first; spend capped per check
  • A fix that fails any identity goes to a person, never shipped as proven

How proof works

lab: three-identity probe, simplified from the real run
-- 1. anonymous visitor, with your public key
set local role anon;
select count(*) from public.profiles;   -- 2: LEAK
-- 2. signed-in stranger
set local role authenticated;
select set_config('request.jwt.claims', '{"sub":"<stranger>"}', true);
select count(*) from public.profiles;   -- 2: LEAK
verify a receipt · python, simplified
r = get(f"{API}/receipts/{check_id}")
key = get(f"{API}/.well-known/patchlabs-receipt-key")
msg = json.dumps(r["receipt"], sort_keys=True,
                 separators=(",", ":")).encode()
Ed25519PublicKey.from_public_bytes(
    b64decode(key["public_key"])).verify(
    b64decode(r["signature"]), msg)

In your workflow

From your terminal, your agent or your CI.

All integrations
CIlive

GitHub Action

Re-check when a migration lands and fail the build while a leak is open. Setup.

Agentslive

MCP server

Claude Code, Cursor, VS Code, Windsurf. Setup.

APIlive

REST API and webhooks

Signed events and a workspace key. Reference.

Decidelive

Approve or mark intended

Record decisions on each check; suppressions stop repeat alerts. Decisions.

Findingslive

Stable IDs, 21 checks live

PL-001 to PL-026, each with the pattern and the fix. Library.

GitHub Appcoming

Pull requests

Fixes as pull requests on your repo, and private repos. Coming.

Questions

Engineer questions.

Something not covered? Email the founder.

What does the lab not model?

Anything outside your migrations: changes made by hand in the dashboard, extensions or settings not in the repo, and backends other than Supabase/Postgres. The report lists what it couldn’t rebuild.

Does it understand intentionally public tables?

Mark them as intended once; later checks keep reporting them but stop alerting. Decisions go into the signed receipt.

Can I see the raw findings?

Yes. Every finding has the same JSON shape across the report, API and webhooks: ID, severity, object, file, line, evidence, proof and fix.

Is this a pentest?

No. It tests specific, documented things in depth. Use it alongside a pentest for a high-stakes launch.

Free check

Run it on a repo you know well.

The fastest way to judge the proof is on code you understand. First app free.