Sample · fictional app
Proof report: Parcelry
This is what a Launch Pass report looks like. Parcelry is a made-up parcel-tracking SaaS built with Lovable on Supabase and Stripe. The findings, pull request and test results below are illustrative. Your report uses the same structure with your app's real results.
Summary
We found four launch blockers. All four are fixed in one pull request, and every fix was proven on the staging copy after the merge. One item (AI spend caps) is out of scope for a Launch Pass and is listed as a recommendation.
| Check | Found | Fixed | Proven |
|---|---|---|---|
| Row level security | RLS off on shipments; using (true) on addresses | PR #42 | 16 / 16 pass |
| Supabase grants | anon had ALL on 3 tables | PR #42 | verified |
| Stripe webhooks | No event-ID check: a retried checkout.session.completed added a second seat | PR #42 | 6 / 6 pass |
| Auth redirects | Magic link pointed at localhost:3000 | PR #42 | verified |
| Email limits | Default Supabase SMTP (rate-limited) | Custom SMTP configured by owner | verified |
Proof 1: user B cannot reach user A's data
Two test accounts, A and B. Signed in as B, we tried every operation against rows owned by A, through the same public API key the app ships in its browser bundle.
| Table | Select | Insert as A | Update | Delete |
|---|---|---|---|---|
shipments | 0 rows | denied | 0 rows | 0 rows |
addresses | 0 rows | denied | 0 rows | 0 rows |
invoices | 0 rows | denied | 0 rows | 0 rows |
profiles | own row only | denied | 0 rows | 0 rows |
Before the fix, the same test as B returned 1,204 of A's shipment rows.
Proof 2: each payment grants access exactly once
Replayed in Stripe test mode against the fixed webhook handler. The rule under test: one paid event changes one entitlement, once.
| Replay | Before | After |
|---|---|---|
| Same event delivered twice | 2 seats | 1 seat |
| Two deliveries at the same time | 2 seats | 1 seat |
| Retry after a timeout | 2 seats | 1 seat |
subscription.deleted before created | Pro kept | Pro removed |
| Unsigned event | accepted | rejected, 400 |
| Wrong signing secret | rejected | rejected, 400 |
What changed in PR #42
- Enabled RLS on all public tables; replaced
using (true)with owner-scoped policies. - Least-privilege grants:
anonreduced to read onplansonly. - Webhook handler verifies the signature and records each Stripe event ID in a table with a unique constraint before changing access.
- Site URL and redirect allow-list set to the production domain.
- Tests added so the isolation and replay checks run again on the next change.
Recommendations (out of scope)
- Add auth and a daily spend cap to
/api/summarize, which calls the model provider. This is covered by Launch Pass Pro.
Scope and limits
This report covers the checks above, on the staging environment, as of the scope date. It is not a guarantee that the application cannot be breached. Client data used for testing is deleted within 14 days of delivery.