Clerk Gates contract
clerk-gates verifies Clerk Billing plan and feature gates on protected routes. Use it for pure
Clerk Billing apps where Clerk owns plans and subscriptions, so the Access contract does not apply.
This contract is static and config-based. It does not call the live Clerk API, store Clerk data, or verify real subscription state.
Example
version: 1
contracts:
- type: clerk-gates
scan_paths:
- app/**/*.ts
- app/**/*.tsx
- src/**/*.ts
- src/**/*.tsx
billing_config_file: clerk-billing.json
rules:
- id: export-api
paths:
- app/api/export/**
require:
feature: export
target: user
severity: high
- id: team-dashboard
paths:
- app/dashboard/team/**
require:
plan: org:team
target: organization
severity: high
Refresh the optional local Clerk Billing config export with:
clerk config pull --keys billing > clerk-billing.json
When clerk-billing.json exists, ProdVerdict validates that referenced plan and feature slugs are
present. When it is missing, slug validation is skipped without failing the check.
What it checks
- Matching files contain a server-side
auth()call from@clerk/nextjs/server. - Matching files call
has({ feature: "..." })orhas({ plan: "..." })for the configured slug. - Organization rules check org context before the Clerk Billing gate.
- Client-only helpers such as
useAuth()and<Show>are not treated as sufficient protection for API or server-rendered money paths.
CLI
npx prodverdict check clerk-gates
npx prodverdict check all --format agent
See core/examples/nextjs-clerk-billing/ for a minimal pass example.
Not covered
clerk-gates does not verify usage metering, credits, seat counts, real subscription state, or live
Clerk Dashboard configuration. Those remain separate roadmap areas.