Zum Inhalt springen

Secrets-Rotation

Orimoras Secrets erfüllen zwei verschiedene Aufgaben und rotieren entsprechend unterschiedlich:

  • Verschlüsselungsschlüssel (*_ENCRYPTION_KEY, AES-256-GCM) verschlüsseln gespeicherte Geheimnisse — sie sind umkehrbar, Rotation heißt also: die Daten mit dem neuen Schlüssel neu verschlüsseln (per Skript).
  • HMAC-Secrets (*_SECRET) hashen Tokens at rest — sie sind einwegig, Rotation nutzt also entweder ein Dual-Key-Fenster oder erfordert das Neuausstellen der betroffenen Tokens.
SecretSchütztRotation
IDENTITY_ENCRYPTION_KEYSSO-Provider-Konfigs/SecretsRe-Encrypt-Skript
MFA_ENCRYPTION_KEYTOTP-SecretsRe-Encrypt-Skript
LLM_ENCRYPTION_KEYGespeicherte KI-Provider-API-KeysRe-Encrypt-Skript
PUBLISHING_ENCRYPTION_KEYWebhook-/Publishing-Secrets, Off-Site-KonfigRe-Encrypt-Skript (+ Off-Site neu speichern)
API_KEY_SECRETREST-API-Keys (langlebig)Dual-Key-Fenster (API_KEY_SECRET_PREVIOUS)
SCIM_TOKEN_SECRETSCIM-Provisioning-TokensTokens neu ausstellen
MAGIC_LINK_SECRETMagic-Links (15 Min), Einladungen, Fallback-RootKurzes Fenster; Einladungen ggf. neu
SESSION_SECRETStep-up- (10 Min) + MFA-Pending- (5 Min) CookiesJederzeit — Sessions sind nicht betroffen

Verschlüsselungsschlüssel werden mit scripts/rotate-encryption-key.mjs rotiert: das Skript entschlüsselt jede betroffene Zeile mit dem alten Schlüssel und verschlüsselt sie atomar mit dem neuen neu. Jede Zeile wird vor dem Schreiben per Roundtrip selbst geprüft, und jede Zeile, die sich nicht mit dem alten Schlüssel entschlüsseln lässt, bricht den gesamten Lauf ab — kein Teilzustand.

  1. Neuen 32-Byte-Schlüssel erzeugen:

    Terminal-Fenster
    node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
  2. Dry-Run (liest + validiert alles, schreibt nichts):

    Terminal-Fenster
    node scripts/rotate-encryption-key.mjs --key llm \
    --old "$OLD_KEY" --new "$NEW_KEY" --dry-run

    --key ist eines von identity, mfa, llm, publishing. Es gibt eine Zeilenzahl pro Tabelle aus.

  3. Anwenden (eine Transaktion):

    Terminal-Fenster
    node scripts/rotate-encryption-key.mjs --key llm --old "$OLD_KEY" --new "$NEW_KEY"
  4. Env-Variable umstellen auf den neuen Wert (z. B. LLM_ENCRYPTION_KEY=$NEW_KEY) und die App neu starten.

  5. Verifizieren, dass die betreffende Funktion läuft (z. B. eine KI/LLM-Konfig oder ein Webhook), dann den alten Schlüssel verwerfen.

Das Chiffrat-Format trägt keine eingebettete Schlüsselversion, daher verschlüsselt die Rotation den gesamten Datensatz neu (statt zeilenweise lazy). Eine künftige Erweiterung (Schlüssel-ID im Payload) könnte rollierende Rotation ermöglichen; bis dahin ist der atomare Voll-Re-Encrypt des Skripts der unterstützte Weg.

REST-API-Keys werden HMAC-gehasht und können nicht neu gehasht werden (das Klartext-Token wird nicht gespeichert). Um ohne Integrations-Bruch zu rotieren, nutze ein Dual-Key-Fenster:

  1. Setze den alten Wert als API_KEY_SECRET_PREVIOUS und den neuen als API_KEY_SECRET, dann deployen. Bestehende Keys bleiben gültig (Orimora akzeptiert beide Secrets).
  2. Stelle API-Keys über dein gewähltes Fenster neu aus (Nutzer regenerieren sie unter Einstellungen → Entwickler). Neue Keys werden unter dem neuen Secret gehasht.
  3. Sobald alte Keys ausgemustert sind, entferne API_KEY_SECRET_PREVIOUS und deploye erneut. Jeder noch auf dem alten Secret laufende Key wird ungültig.
  • SCIM_TOKEN_SECRET — den SCIM-Token des Teams auf der SSO/SCIM-Admin-Seite neu ausstellen und im IdP aktualisieren. (Vorher auf einen unabhängigen Wert setzen, falls er aktuell auf API_KEY_SECRET zurückfällt.)
  • MAGIC_LINK_SECRET — macht laufende Magic-Links (15 Min) und offene Einladungen ungültig. Ist er nicht unabhängig gesetzt, ist er außerdem der Fallback für API_KEY_SECRET/SCIM_TOKEN_SECRET/EMAIL_CHANGE_SECRETsetze diese vorher unabhängig, sonst machst du auch API-Keys ungültig. Bei geringer Last rotieren; Einladungen ggf. neu ausstellen.
  • SESSION_SECRET — signiert nur kurzlebige Step-up- (10 Min) und MFA-Pending- (5 Min) Cookies; Sessions selbst sind zufällige Datenbank-IDs und nicht betroffen. Jederzeit rotierbar — schlimmstenfalls re-verifiziert ein Nutzer mitten im Step-up.
  • Bestätige, dass die betroffene Funktion end-to-end läuft.
  • Halte den vorherigen Schlüssel/Secret (offline) verfügbar, bis die Verifikation besteht, dann vernichten.
  • Notiere die Rotation (Datum, welches Secret) in deinem Change-Log für den Audit-Trail.