Webhook contract
Static lint for webhook handlers (Stripe, Paddle, GitHub, Clerk, etc.).
What it catches
- Missing signature verification (
constructEvent,verifyWebhook, signature headers) - Missing idempotency (
event.id,processed_events,ON CONFLICT) - Missing raw body reads when signature verification requires them
Example config
version: 1
contracts:
- type: webhook
handler_paths: [app/api/**/webhook/**, src/**/webhook/**]
require_idempotency: true
require_raw_body: true
severity: high
CLI
npx prodverdict check webhook --config prodverdict.yml
Runs on every PR. No billing secrets required.