The Pre-launch check costs $490 and takes 48 hours from access to report. This post walks through those two days so you know what you are buying and what you are not. The check covers five categories: secrets, data access, login and permissions, reliability, and deploy configuration. Payments and AI features are separate packages.
Hour zero: access
We need three things. The live URL of the app, or the preview URL if you have not launched. Permission to create two test accounts, or two accounts you create for us. And, if you are willing, read-only access to the repository or the builder project so we can read the source as well as the running app. Source access makes the findings more precise, but the check runs without it, because most of what we test is visible to any visitor.
We do not ask for your production database password, your Supabase secret key or your Stripe secret key. If a finding needs one of those to confirm, we describe the check for you to run instead.
The bundle read
The bundle is the JavaScript your app sends to every browser. We download it from the live site and extract every string shaped like a credential, then decode each one to learn which role it carries. A Supabase publishable key is expected. A secret key, a Stripe sk_ key or a model provider's key is a critical finding, and we call the project's API with it to confirm the role rather than guessing from the prefix. We also read the environment variables that reached the browser and the URLs the app calls, which gives us the map for the next steps.
The API as a stranger and as two users
Every address the app calls, we call three ways: signed out, signed in as account A, and signed in as account B. For each table or endpoint we ask the same four things: whether a stranger can read it, whether A can read B's rows, whether A can change or delete B's rows by changing an id in the request, and whether a free account can reach an endpoint the paid plan is supposed to gate.
On Supabase we enumerate tables: with the publishable key, we ask the REST API which tables answer, and we test each one with no filter. Supabase's own defaults help here, since dashboard-created tables get Row Level Security by default and Security Advisor flags tables without it, and we compare what the advisor says with what the API actually returns. On Firebase the equivalent is reading Firestore with the client config as an anonymous user. The patterns this finds are Record ids accepted without an ownership check, RLS disabled on a table and Authorization enforced only in the browser.
Admin routes, error behaviour, headers
We try the obvious admin addresses, /admin, /dashboard/admin, /api/admin and the ones we spotted in the bundle, as a stranger and as a normal user. A page that renders, or an API that answers, without a role check is a finding, even when the navigation hides the link.
Then we make the app fail on purpose: malformed ids, oversized inputs, a request with the wrong content type. We read what comes back. Stack traces, database error text and internal hostnames in a response are findings, because they hand an attacker the map. We also try the password reset and login endpoints repeatedly to see whether anything slows us down; a public endpoint with no rate limit is reported.
Last, we read the response headers on the production site and note which security headers are absent, and whether debug settings are on. These are usually medium severity and quick to fix.
Writing the report
The report has two layers. The first page is written for a non-engineer: what we tested, how many findings by severity, what the critical ones mean in plain terms, and what to fix first. Every finding below that carries a severity, the mechanism in one sentence, the affected path, the exact output we observed, a fix direction you can hand to your developer or paste into your builder's chat, and how we will re-check it. We also list what we tested and did not find, so you know the negative results too.
A synthetic example of the whole document is at Sample report. Delivery includes a 30-minute walkthrough call, and we re-check critical findings after your fixes within 14 days at no extra cost. If the report does not contain at least one actionable finding, or you are not satisfied with its depth, tell us within 7 days of delivery and we refund the package in full.
What the check does not do
We test against a defined checklist and report what we find. We do not guarantee that an app is free of vulnerabilities. We are not a certified penetration-testing firm and do not issue compliance attestations. We do not rebuild your app; fixes are yours or your developer's, and we re-check them.
Findings describe what we observed on the version you gave us access to, on the date of testing. Changes after that date are not covered until re-checked. The full list is at What we cannot do, and the ordering process is at How it works.
What to do this week
- Run the two-account test yourself before ordering; it is the same first step we take: Record ids accepted without an ownership check.
- Search your bundle for a secret key: Service-role key shipped in the browser bundle.
- Work through the self-check to see which categories apply to your stack: Self-check.