Skip to main content

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: "..." }) or has({ 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.