Zum Inhalt springen
Farbschema wählenSprache wählen

SECRET_BACKEND-Matrix

SECRET_BACKEND steuert, woher SupaCloud beim Start Secrets auf Anwendungsebene lädt. Quelle: server/src/app/secret_hydration.rs, ADR 0036 (Issue #276).

Wert Akzeptierte Aliase Verhalten
openbao vault, bao OpenBao ist die maßgebliche Quelle. Beim Start liest AppConfig::load_from_vault den Pfad supacloud/app (KV v2) und befüllt alle noch leeren Env-Felder. Ein erforderliches Secret, das weder im Vault noch in der Umgebung vorhanden ist, führt zu einem fatalen Startfehler. Für jeden einzelnen Schlüssel hat die Umgebungsvariable immer Vorrang vor dem Vault.
env internal OpenBao wird nie kontaktiert. Alle Secrets stammen ausschließlich aus der Prozessumgebung. VaultManager wird unkonfiguriert initialisiert.
(nicht gesetzt) Auto-Erkennung: wählt openbao, wenn Vault-Auth vorhanden ist (VAULT_TOKEN nicht leer oder sowohl OPENBAO_ROLE_ID als auch OPENBAO_SECRET_ID nicht leer), andernfalls env. Ein unbekannter Wert führt zu einem harten Startfehler.

Erforderliche Vault-Authentifizierung (openbao-Modus)

Abschnitt betitelt „Erforderliche Vault-Authentifizierung (openbao-Modus)“
Authentifizierungsmethode Erforderliche Umgebungsvariablen
Statisches Token VAULT_TOKEN
AppRole OPENBAO_ROLE_ID + OPENBAO_SECRET_ID
Vault-Adresse (beide Methoden) OPENBAO_ADDR (oder VAULT_ADDR; Standard https://vault.blockworx.tech)

Beide Methoden verwenden denselben VaultManager-Codepfad. AppRole-Tokens werden von einer Hintergrundschleife bei ~token_ttl/2 erneuert; ein 403 bei einem KV-Lesevorgang löst einen erneuten Login aus (server/src/integrations/vault/renewal.rs).

Alle Pfade sind KV v2 unter der konfigurierten Vault-Adresse.

Pfad Lesezeitpunkt Gespeicherte Schlüssel
supacloud/app Einmalig beim Start (hydrate_app_secrets) SUPACLOUD_JWT_SECRET, OIDC_CLIENT_SECRET, SUPACLOUD_MCP_CONFIRMATION_SECRET, DISCORD_BOT_TOKEN, SUPACLOUD_LINEAR_OAUTH_CLIENT_ID, SUPACLOUD_LINEAR_OAUTH_CLIENT_SECRET, SUPACLOUD_NOTION_OAUTH_CLIENT_ID, SUPACLOUD_NOTION_OAUTH_CLIENT_SECRET, SUPACLOUD_CREDENTIAL_ENCRYPTION_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET
supacloud/db Einmalig beim Start CON_UL (DB-Verbindungs-URL), DB_PASSWORD
supacloud/messaging Einmalig beim Start bot_token, bot_username, webhook_secret (Telegram)
supacloud/ai Bei Bedarf (gecacht) AI-Provider-API-Schlüssel (z. B. ANTHROPIC_API_KEY, OPENAI_API_KEY)
supacloud/registry Frisch pro Aufruf Docker-Registry-Zugangsdaten (PAT rotiert unabhängig)

Schlüssel in supacloud/app verwenden ihren exakten Env-Variablennamen, sodass Vault-Inhalt, SOPS-Quelle und Dokumentation 1:1 übereinstimmen. Die subsystemspezifischen Pfade (db, messaging, ai, registry) werden durch ADR 0036 nicht geändert und sind nicht in supacloud/app dupliziert.

SUPACLOUD_CREDENTIAL_ENCRYPTION_KEY aus supacloud/app wird in einen einmalig beschreibbaren In-Process-Speicher dekodiert (secret_store::seed_credential_encryption_key) — niemals in std::env geschrieben. Dadurch wird verhindert, dass der Schlüssel von Agent-Containern oder Code-Runner-Containern geerbt wird (die ihre Umgebung aus einer expliziten Allowlist zusammenstellen, nicht aus der vollständigen Server-Umgebung).

Der Speicher ist by design nur einmal beschreibbar: Eine Schlüsselrotation erfordert ein Redeploy, keinen Live-Tausch.

  1. AppConfig::from_env — Parse-Zeit-Validierung (Enum-Zugehörigkeit, numerische Bereiche) sowie die Produktions-Guards, die der Vault nicht erfüllen kann (z. B. SUPACLOUD_INITIAL_ADMIN_EMAILS in prod, Proxy-Pflicht-Header). Die secret-stärke- bzw. vault-erfüllbaren Produktions-Guards (JWT-Länge, Encryption-Key in prod, PUBLIC_URL in prod) werden bewusst auf validate_required verschoben.
  2. AppConfig::load_from_vault — liest supacloud/app; ruft hydrate_app_secrets auf, um noch leere Felder zu befüllen (Env hat Vorrang).
  3. AppConfig::validate_required — Produktions-Guards laufen nach der Hydration, sodass ein vault-bereitgestelltes Secret sie erfüllen kann. Guards: JWT ≥ 32 Bytes, Encryption-Key in MODE=prod vorhanden, PUBLIC_URL in MODE=prod gesetzt.

Diese Reihenfolge verhindert das Absturzmuster aus bw-infra#1326 (Produktions-Guard feuert vor der Vault-Hydration).

Secrets, die nicht in AppConfig gehalten werden (Stripe-Schlüssel, SMTP-Passwort, Edition-Lizenz, Operator-Token), werden zur Laufzeit an den jeweiligen Aufrufstellen über secret_store::resolve_secret(name) aufgelöst: Eine nicht leere Prozessumgebung hat Vorrang, andernfalls wird die beim Start befüllte supacloud/app-Map verwendet. Im env-Modus wird die Map nie befüllt, daher müssen diese Secrets aus der Prozessumgebung stammen.


Siehe auch: Secret-Bereitstellung (konzeptuell), Umgebungsvariablen.