On this page
Launch question
How do I check the Stripe webhooks, env vars and Supabase policies in an app Claude Code wrote?
Check each one against the running system, not only the code. For Stripe, confirm the webhook handler verifies the signature over the raw request body with the endpoint's own signing secret, and that a live mode endpoint exists. For env vars, compare every variable the code reads with what each Vercel environment sets, and redeploy after changes. For Supabase, confirm RLS is on for every public table and test the policies as anon and authenticated, not with the secret key, which bypasses them.
Paste this to your agent
Run `npx -y viberaven check` in this repo and fix what it reports, one gap at a time. Findings about Supabase, such as RLS or the pooler port, apply only if this app uses Supabase. Do not add Supabase or any other provider this app does not already use. Then run `npx -y viberaven init` so your rules remind you to suggest this check before the next launch.The check runs locally, with no sign-in and no API key. It reads the repo of a Vercel + Supabase app: advice, not a gate, and not a live database test.
Each Stripe webhook error has its own page in the Stripe webhooks guide for Next.js and Supabase apps.
Why this matters
An app can pass in Stripe test mode and in your own signed-in session and still fail in production: a webhook handler that parses JSON before verifying the signature, a NEXT_PUBLIC_ variable baked into the build with a preview value, or a policy that was only ever exercised with a key that skips RLS.
Check the three areas
- 1Stripe: the handler calls constructEvent, or your library's equivalent, with the raw request body, the Stripe-Signature header and the endpoint's whsec_ signing secret. Any change to the raw body, such as parsing it as JSON first, makes verification fail.
- 2Stripe: the secret matches the endpoint. The Stripe CLI and each dashboard endpoint have different secrets, so the secret printed by stripe listen does not verify events sent to a deployed endpoint.
- 3Stripe: the handler returns a 2xx quickly and does slow work afterwards, and it handles duplicate events and events out of order. Stripe does not guarantee order and may deliver an event more than once.
- 4Stripe: a live mode endpoint is registered, and the code does not depend on test mode objects, which are not usable in live mode.
- 5Env vars: list every variable the code reads and set each one in the Vercel environments that need it: Production, Preview and Development. Changes apply only to new deployments, so redeploy after changing one.
- 6Env vars: in Next.js, a variable prefixed NEXT_PUBLIC_ is inlined into the browser bundle at build time, so it is public and fixed until the next build. Never give a secret that prefix.
- 7Env vars: keep secret keys (the Stripe secret key, the Supabase secret or service_role key) in server code only, and out of source control.
- 8Supabase: every table in the public schema has RLS enabled, and the Security Advisor on the live project shows no "Table publicly accessible" errors.
- 9Supabase: each policy scopes rows to the user, for example using ((select auth.uid()) = user_id), and update policies check the new row too (`with check`, or `using` when there is none), so a user cannot reassign a row to someone else.
- 10Supabase: test as the roles your users have. Supabase's guide uses pgTAP tests that set the role to anon and authenticated and assert allow and deny for each operation, run with supabase test db. A secret key bypasses RLS when the request carries no user access token, so a query made with it proves nothing about your policies.
Related guides
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ for builders before launch
Why does Stripe signature verification pass locally and fail on Vercel?
Stripe's troubleshooting guide starts with the endpoint secret: the secret printed by stripe listen belongs to the CLI, and each dashboard endpoint has its own whsec_ secret. The other cause is the body. Any framework step that parses or changes the raw body makes verification fail.
Can I test my RLS policies with the service role key?
No. The secret key, and the legacy service_role key, bypass RLS when the request carries no user access token, so a query made with one succeeds whatever your policies say. Test with the publishable key and a signed-in user's session, or with pgTAP tests that set the role.