Skip to content

enterprise-api: signup activation preserves free-signup tier instead of the paid tier (SUSE incident) #92

Description

@sre-helmcode

Bug

ActivateSignupOrg (first-activation webhook path) preserved tier + key_limit from the free-signup row instead of writing the tier the buyer actually paid. A free-signup org that pays a checkout for a different tier ends up with signup-tier entitlements at the paid tier's price.

Production evidence (2026-09-18)

Org SUSE Software Solutions Germany GmbH (3e5b8734-5e29-436a-bffe-b1b120322de5):

  • Free signup 2026-09-16 chose growth (3 expired growth checkout sessions).
  • Paid a starter checkout (EUR 399) on 2026-09-17 09:54 UTC (sub_1UGc3VBF7qtPjBKwYWeVR9Yl).
  • DB kept tier=growth, key_limit=15 -> dashboard advertised Growth EUR 1,299 while Stripe billed Starter EUR 399; LiteLLM caps + 15-key limit granted at starter price.
  • Sweep of all 23 orgs with subscriptions: SUSE was the only affected row.
  • Data fix applied on prod 2026-09-18 09:49 UTC (tier->starter, key_limit->5).

Root cause

  • internal/db/queries/organizations.sql ActivateSignupOrg comment: "preserves tier + key_limit (set on signup row insert)".
  • provisionAndWelcomeOrg receives the paid tier but only used it for the welcome email.
  • The SEPA settle path (onInvoicePaymentSucceeded -> provisionAndWelcomeOrg(..., org.Tier, ...)) had the same flaw.

Fix

  • ActivateSignupOrg writes tier + key_limit; callers derive the paid tier from the checkout session metadata (card path) or the settled invoice's price metadata (tierFromInvoice, SEPA settle path), falling back to the org's existing values when absent.
  • Branch: fix/signup-activation-tier-reconciliation (enterprise-api), VERSION 0.4.89.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    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