Skip to content

enterprise-api: enforce key-cap check server-side on downgrade checkout #97

Open

Description

@sre-helmcode

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:

  1. 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.
  2. 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.

Source review: https://github.com/helmcode/enterprise-ui/pull/23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions