Editionen und Berechtigungen
Deployment-Edition
Abschnitt betitelt „Deployment-Edition“Jede SupaCloud-Instanz läuft in einer von zwei Editionen: Community oder Enterprise. Die Edition ist eine Eigenschaft des Deployments, nicht einer einzelnen Organisation oder eines Workspaces. Sie wird einmalig beim Start aufgelöst, für die Laufzeit des Prozesses zwischengespeichert und ist fail-closed: Alles außer einer gültigen, nicht abgelaufenen Enterprise-Lizenz wird als Community aufgelöst.
Community
Abschnitt betitelt „Community“Der Standard. Die Verfügbarkeit von Funktionen wird pro Organisation durch das Stripe-Abonnement und den Plan bestimmt. Eine Organisation ohne aktives Abonnement fällt auf den free-Plan zurück, wenn die Abrechnung erzwungen wird, oder auf den historischen Grant-all-Fallback legacy bei einer selbst gehosteten Instanz, die Stripe nie konfiguriert hat.
Enterprise
Abschnitt betitelt „Enterprise“Wird durch ein gültiges HS256-JWT in SUPACLOUD_EDITION_LICENSE freigeschaltet, das gegen SUPACLOUD_EDITION_SECRET (mindestens 32 Bytes) verifiziert wird, dessen edition-Claim enterprise ist und dessen exp noch nicht abgelaufen ist. Beide Secrets werden über den supacloud/app OpenBao-Pfad geladen, wenn SECRET_BACKEND=openbao gesetzt ist (siehe Secret-Bereitstellung).
Wenn die Edition auf Enterprise aufgelöst wird, schließt workspace_entitlements kurz auf den vollständigen legacy_features-Grant — jedes boolesche Feature aktiviert und jedes Kontingent auf "unlimited" gesetzt (mit Ausnahme von support_tier, das auf den String "legacy" gesetzt wird) — für jeden Workspace auf der Instanz, unabhängig von einem Stripe-Abonnement. Die resultierende EntitlementSummary meldet plan_id: "enterprise" und status: "edition". Workspace- und benutzerspezifische Overrides gelten weiterhin obendrauf (siehe unten).
Entwicklungs-Bypass
Abschnitt betitelt „Entwicklungs-Bypass“MODE=dev in Kombination mit SUPACLOUD_EDITION=enterprise aktiviert Enterprise ohne einen Lizenz-Token. Dieser Pfad wird niemals berücksichtigt, wenn MODE auf prod oder production gesetzt ist.
Berechtigungs-Vorrang
Abschnitt betitelt „Berechtigungs-Vorrang“Bei einem Community-Deployment (oder wenn Overrides auf den Enterprise-Grant angewendet werden müssen) werden Feature-Werte über eine fünfstufige Kette aufgelöst. Die erste Schicht, die einen Wert für einen bestimmten Feature-Schlüssel definiert, gewinnt; Schichten mit niedrigerer Priorität werden weder zusammengeführt noch gemittelt.
Benutzer-Override ?? Seat-Typ ?? Workspace-Override ?? Org-Plan (Abonnement → plan.features) ?? Standard (Free-Plan oder Legacy-Grant-all)Die Basiskarte (Standard / Org-Plan, Schichten 1-2) wird in workspace_entitlements erstellt; die drei Override-Schichten (Workspace-Override, Seat-Typ, Benutzer-Override — Schichten 3-5) werden anschließend, von der niedrigsten zur höchsten Priorität, in apply_active_overrides (services/billing/features.rs) angewendet:
| Priorität | Quelle | Speicherort |
|---|---|---|
| 5 — höchste | Benutzer-Override | feature_overrides-Zeile mit gesetzter user_id |
| 4 | Seat-Typ | seat_types.entitlements über organization_members.seat_type_id |
| 3 | Workspace-Override | feature_overrides-Zeile mit gesetzter workspace_id, user_id NULL |
| 2 | Organisations-Plan | subscriptions → plans.features (über workspaces.organization_id) |
| 1 — niedrigste | Standard | free-Plan-Seed oder legacy-Grant-all bei nicht abonniertem Self-Hosting |
Was jede Schicht steuert
Abschnitt betitelt „Was jede Schicht steuert“Organisations-Plan. Der Basis-Berechtigungssatz stammt aus der plans.features JSONB-Spalte des aktiven Abonnements. Im Free-Tier tragen Kontingent-Schlüssel wie users.max eine kleine numerische Obergrenze; mittlere kostenpflichtige Pläne (pro/team) tragen größere numerische Obergrenzen; nur der Enterprise-Plan (und der private Legacy-Plan) trägt "unlimited".
Workspace-Override. Eine feature_overrides-Zeile, die auf einen Workspace beschränkt ist (ohne user_id), erlaubt es einem Operator, einen bestimmten Feature-Schlüssel für alle in diesem Workspace zu erweitern oder einzuschränken, unabhängig vom Plan. Läuft ab, wenn expires_at überschritten wird oder wenn die Zeile widerrufen wird.
Seat-Typ. Jedem Mitglied einer Organisation kann ein seat_type über organization_members.seat_type_id zugewiesen werden. Ein Seat-Typ trägt eine Teilmenge desselben Feature-Schlüssel-Vokabulars wie plans.features. Im Seat-Typ vorhandene Schlüssel überschreiben den Workspace-/Plan-Wert für diesen Benutzer; fehlende Schlüssel werden an die nächstniedrigere Schicht weitergegeben. Dies ermöglicht eine benutzerspezifische Stufen-Schärfung (zum Beispiel die Gewährung von sso_oidc_byo für Operatoren, während Mitglieder auf einem eingeschränkten Seat bleiben).
Benutzer-Override. Eine feature_overrides-Zeile, die auf einen bestimmten Benutzer beschränkt ist, ist die Quelle mit der höchsten Priorität und überschreibt jede andere Schicht. Reserviert für Ausnahmefälle wie Support-Vereinbarungen oder temporäre Zuweisungen.
Semantik der Feature-Werte
Abschnitt betitelt „Semantik der Feature-Werte“Ein Feature-Wert ist entweder:
true— die Funktion ist ohne numerische Begrenzung aktiviert.false/null/ nicht vorhanden — die Funktion ist deaktiviert;require_featuregibt403 Forbiddenzurück."unlimited"— gilt für Kontingent-Schlüssel (z. B.runs.per_month); es wird keine Obergrenze erzwungen.- eine Zahl — eine harte Obergrenze;
require_below_limitprüft die aktuelle Anzahl vor dem Erlauben der Operation.
Verwandte Themen
Abschnitt betitelt „Verwandte Themen“- Secret-Bereitstellung — wie
SUPACLOUD_EDITION_LICENSEundSUPACLOUD_EDITION_SECRETaus OpenBao geladen werden. - ADR 0035 (Organisations-Mandantschaft) und der
#305Editions-Kurzschluss —docs/decisions/0035-organization-tenancy-seats-invites-secret-scoping.md. - Quelle:
server/src/app/edition.rs,server/src/services/billing/features.rs.