You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
enterprise-api: enforce key-cap check server-side on downgrade checkout #97
Found by the Opus security review of enterprise-ui#23 (in-console plan switcher).
Gap:POST /api/billing/checkout-session accepts any valid tier for an active org without consulting CanDowngrade. A direct API call can downgrade an org holding more active keys than the target tier allows; the webhook then writes the lower key_limit and clamps only the aggregated key (standard keys stay over-cap). There is also a timing window between any precheck and the webhook landing.
Pre-existing: the endpoint always accepted any tier; ARCHITECTURE.md §5.1 documents the check as client-side pre-check. The new UI does not widen the gap (it fail-closes honest users), but the UI precheck should be a convenience, not the only gate.
Proposal:
In CheckoutSession (internal/handlers/billing.go), when the requested tier is LOWER than the org's current tier, compare CountActiveApiKeysByOrg vs TierKeyLimits[target] and return 409 downgrade_requires_revoke when over-cap.
Optionally re-check in the checkout.session.completed upgrade path (same transaction as the tier write).
Tests: extend billing_test.go + webhook_test.go for the over-cap downgrade refusal and the timing case.
Activity