Access contract
Compares billing subscription state (Stripe or Paddle) against your application database.
Rules (summary)
| # | Condition | Severity |
|---|---|---|
| 1 | Active/trialing sub + has_paid_access = false | high (revenue leak) |
| 2 | Cancelled/unpaid sub + has_paid_access = true | high (wrongful access) |
| 3 | Same stripe_customer_id on 2+ users | medium |
| 4 | Active price ID not in plans map | high |
| 5 | DB plan ≠ mapped plan for active sub | high |
| 6 | User has customer ID but no Stripe sub | medium |
| 7 | Active Stripe customer, no app user | low |
Rules 4–5 require a plans: block in config.
CLI
npx prodverdict check access
npx prodverdict check access --config ./prodverdict.yml
npx prodverdict check access --fixtures --fixtures-dir scenarios/fail-revenue-leak
npx prodverdict check access --format json
npx prodverdict check access --strict # fail on warn
Exit codes
| Code | Meaning |
|---|---|
| 0 | pass or warn (without --strict) |
| 1 | fail (high severity) |
| 2 | config / credential error |
Paddle
Use source_of_truth: paddle and PADDLE_API_KEY. See SDK example examples/paddle-stripe/.