Nutzen Sie diese Übersicht, um zu entscheiden, welche Werte in die Runtime-Umgebung gehören, welche in die Datenbank generiert werden und welche von Plugins gespeichert werden. Jeder Abschnitt beschreibt, wie Rotation eine laufende Site beeinflusst.
Unter Node.js legen Sie Runtime-Geheimnisse im Secret-Manager der Hosting-Plattform ab, damit sie beim Start in process.env gelangen. Für einen Worker verwenden Sie wrangler secret put. Legen Sie keine Geheimniswerte in astro.config.mjs, wrangler.jsonc oder import.meta.env ab; Vite kann Build-Zeit-Werte in das Server-Bundle einbetten.
Übersicht
| Geheimnis | Quelle | Gespeichert in | Auswirkung bei Schlüsselverlust |
|---|---|---|---|
EMDASH_ENCRYPTION_KEY | Betreiber (emdash secrets generate) | Nur Umgebung / Worker-Secret | Verschlüsselte Plugin-Einstellungen sind erst wieder lesbar, wenn der passende Schlüssel wiederhergestellt ist |
| Preview-Geheimnis | Auto-generiert (Env-Override) | options-Tabelle (emdash:preview_secret) | Ausstehende Preview-Links funktionieren nicht mehr; neue sind in Ordnung |
| IP-Salt | Auto-generiert (Env-Override) | options-Tabelle (emdash:ip_salt) | Kontinuität der Kommentar-Rate-Limits setzt zurück |
| Session- & API-Tokens | Pro Session/Token generiert | Session-Store / Datenbank (nur Hashes) | Nichts — Klartext wird nie gespeichert |
| OAuth-Provider-Zugangsdaten | Sie (Google/GitHub-Konsole) | Umgebung | Anmeldung über diesen Provider stoppt, bis ersetzt |
| Turnstile-Geheimnis | Sie (Cloudflare-Dashboard) | Umgebung | Kommentar-CAPTCHA-Verifizierung schlägt fehl |
| S3-Zugangsdaten | Sie (Speicheranbieter) | Runtime-Umgebung | Medien-Upload/Download schlägt fehl, bis ersetzt |
| Plugin-Geheimnisse | Sie (Admin-Einstellungen-UI) | Verschlüsselte Datenbank-Einstellung | Passenden Verschlüsselungsschlüssel wiederherstellen oder Wert erneut eingeben |
| CLI-Zugangsdaten | emdash login / emdash plugin publish Device-Flows | ~/.config/emdash/auth.json (Modus 0600) | Device-Flow erneut ausführen |
| Register-CLI-Zugangsdaten | emdash-plugin atproto OAuth | ~/.emdash/oauth/, ~/.emdash/credentials.json (Modus 0600) | Erneut anmelden; Identität liegt bei Ihrem PDS |
Der Verschlüsselungsschlüssel
EMDASH_ENCRYPTION_KEY verschlüsselt Plugin-Einstellungen, die mit type: "secret" deklariert sind. EmDash verwendet AES-GCM mit Plugin-ID und Einstellungsschlüssel als authentifizierte Daten. Ein fehlerhafter Wert erzeugt eine betreiberseitige Startmeldung, und Operationen, die verschlüsselte Plugin-Einstellungen brauchen, scheitern geschlossen. Unbezogene Site-Anfragen funktionieren weiter.
Der folgende Befehl erzeugt einen korrekt formatierten Wert. Speichern Sie ihn in der Runtime-Umgebung oder als Worker-Secret, wenn Ihre Deployment diese Variable nutzt.
npx emdash secrets generate
# emdash_enc_v1_<43 base64url chars>
# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY
Das Format ist emdash_enc_v1_ gefolgt von 32 Zufallsbytes als ungepoltes base64url. Der Wert wird vom Betreiber bereitgestellt und nicht in der Datenbank gespeichert. Bewahren Sie ihn in einem Secret-Manager und in einem separaten Wiederherstellungs-Backup auf.
Um den Schlüssel zu rotieren, stellen Sie einen neuen Wert voran und behalten Sie den alten Wert nach einem Komma:
EMDASH_ENCRYPTION_KEY=emdash_enc_v1_<new-key>,emdash_enc_v1_<old-key>
EmDash verschlüsselt neue und erneut gespeicherte Werte mit dem ersten Schlüssel. Es nutzt den gespeicherten kid-Fingerprint, um einen älteren Schlüssel für Lesevorgänge zu wählen. Speichern Sie jedes Plugin-Geheimnis erneut, bevor Sie den alten Schlüssel entfernen, und verifizieren Sie diese Integrationen von einem Deployment, das nur den neuen Schlüssel enthält. EmDash meldet derzeit nicht, welche Schlüssel-IDs noch in Verwendung sind, daher führen Sie eine Inventur der erneut gespeicherten Zugangsdaten und entfernen Sie einen alten Schlüssel erst, wenn jede Integration diese Verifizierung bestanden hat.
Generierte Site-Geheimnisse
Zwei Geheimnisse werden bei erster Nutzung automatisch generiert und in der options-Tabelle persistiert, sodass sie über Anfragen, Deployments und Isolates hinweg stabil sind. Die Generierung ist atomar — gleichzeitige Cold Starts konvergieren auf einen Wert.
Preview-Geheimnis
Signiert Preview-URLs (HMAC). Gespeichert als emdash:preview_secret; 32 Zufallsbytes, base64url.
- Override: setzen Sie
EMDASH_PREVIEW_SECRET(Legacy-Alias:PREVIEW_SECRET), wenn Sie dasselbe Geheimnis über mehrere Prozesse brauchen oder es aus Audit-Gründen pinnen wollen. Die Umgebung gewinnt immer gegenüber dem gespeicherten Wert. - Rotation: löschen Sie die Zeile
emdash:preview_secret(oder ändern Sie die Env-Variable) und deployen Sie neu. Auswirkung: zuvor ausgegebene Preview-Links validieren nicht mehr. Sonst bricht nichts — beim nächsten Preview-Request wird ein frisches Geheimnis generiert (oder aus der Env gelesen). - Bei Verlust: nichts ist unrettbar. Preview-Links sind bewusst kurzlebig.
Siehe den Preview-Leitfaden dazu, wie Preview-URLs gebaut und geprüft werden.
IP-Salt
Salzt den SHA-256-Hash von Kommentierer-IP-Adressen (ip_hash bei Kommentaren) für Kommentar-Rate-Limits. Gespeichert als emdash:ip_salt. Site-spezifisch, sodass Hashes über EmDash-Installationen hinweg nicht korrelierbar sind.
- Override: setzen Sie
EMDASH_IP_SALT. Zur Abwärtskompatibilität werden auchEMDASH_AUTH_SECRET/AUTH_SECRETgeprüft — Installationen, die den Salt historisch daraus ableiteten, behalten stabile Hashes. - Rotation: ändern Sie die Env-Variable oder löschen Sie die Zeile
emdash:ip_salt. Auswirkung: neue Kommentar-Einreichungen hashen zu anderen Werten, sodass das Rate-Limit-Zählen für alle neu startet. Bestehende Kommentare und ihre gespeicherten Hashes bleiben unberührt. - Bei Verlust: kein Datenverlust. Nur die Rate-Limit-Kontinuität setzt zurück.
Session- und API-Tokens
- Sessions nutzen Astros Session-Store (Workers KV auf Cloudflare, Dateisystem unter Node). Das Cookie trägt eine undurchsichtige Session-ID; es gibt kein zu verwaltendes Signaturgeheimnis. Melden Sie sich ab, um eine Session zu beenden, oder leeren Sie den Session-Store (z. B. den KV-Namespace), damit sich alle erneut anmelden müssen.
- API-Tokens (Präfixe
ec_pat_,ec_oat_,ec_ort_) sind undurchsichtige 256-Bit-Zufallswerte; nur ihr SHA-256-Hash wird gespeichert. Der Klartext wird einmal bei der Erstellung angezeigt. Rotieren Sie durch Widerruf und Neuerstellung im Admin. - Einladungs-, Magic-Link- und Wiederherstellungs-Tokens sind zweckgebunden, als SHA-256-Hashes in
auth_tokensgespeichert und zeitlich begrenzt (Einladungen 7 Tage, Magic Links 15 Minuten).
Es gibt nichts proaktiv zu sichern oder zu rotieren: ein Datenbank-Leak legt nur Hashes offen, und jedes Token kann im Admin widerrufen oder neu ausgestellt werden.
Von Ihnen bereitgestellte Dienst-Zugangsdaten
Zugangsdaten für externe Dienste werden aus der Umgebung gelesen und nie in die Datenbank geschrieben. Rotieren Sie sie beim Anbieter, aktualisieren Sie die Variable, deployen Sie neu.
| Dienst | Variablen |
|---|---|
| Google-Anmeldung | EMDASH_OAUTH_GOOGLE_CLIENT_ID, EMDASH_OAUTH_GOOGLE_CLIENT_SECRET (oder ungepräfixte Aliase) |
| GitHub-Anmeldung | EMDASH_OAUTH_GITHUB_CLIENT_ID, EMDASH_OAUTH_GITHUB_CLIENT_SECRET (oder ungepräfixte Aliase) |
| Marketplace-Veröffentlichung (CI) | EMDASH_MARKETPLACE_TOKEN |
| Turnstile (Kommentare) | EMDASH_TURNSTILE_SECRET_KEY (oder TURNSTILE_SECRET_KEY) |
| S3-kompatibler Speicher | S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_BUCKET, S3_REGION |
Unter Cloudflare setzen Sie diese mit wrangler secret put; für die lokale Entwicklung legen Sie sie in .env ab. Wrangler liest entweder .dev.vars oder .env, nicht beides, und .dev.vars hat Vorrang, wenn vorhanden. R2 über ein Binding braucht keine Access-Key-Variablen, weil das Binding Runtime-Zugriff gewährt. Siehe Medienspeicher.
Plugin-Geheimnisse
Einstellungen, die ein Plugin mit type: "secret" deklariert (API-Schlüssel für E-Mail-Anbieter, Formular-CAPTCHAs usw.), werden in der Admin-UI eingegeben und in der options-Tabelle unter plugin:<id>:settings:<key> verschlüsselt. Der Admin erhält nur, ob ein Geheimnis gesetzt ist, auch wenn der passende Verschlüsselungsschlüssel fehlt, sodass ein Administrator eine unlesbare Zugangsdaten ersetzen kann. Plugin-Code liest den Klartext über ctx.settings in seiner isolierten Runtime. Werte, die außerhalb eines deklarierten Einstellungs-Schemas gespeichert werden, einschließlich beliebiger Plugin-KV- und State-Einträge, nutzen diesen Verschlüsselungspfad nicht.
- Zugangsdaten-Rotation: rotieren Sie die Zugangsdaten beim Anbieter und fügen Sie den neuen Wert auf der Einstellungsseite des Plugins ein. Das Speichern schreibt eine neue verschlüsselte Hülle.
- Klartext-Migration: von einer früheren EmDash-Version gespeicherte Geheimnisse bleiben lesbar. Speichern Sie jeden Wert erneut, um ihn zu verschlüsseln.
- Wenn der Verschlüsselungsschlüssel verloren ist: stellen Sie den passenden
EMDASH_ENCRYPTION_KEYaus dem separaten Schlüssel-Backup wieder her. Wenn keine Kopie existiert, ersetzen Sie jede betroffene Zugangsdaten beim Anbieter und geben Sie die Ersatzwerte nach Konfiguration eines neuen Verschlüsselungsschlüssels ein.
CLI-Zugangsdaten
Die emdash-CLI hält zwei Arten von Zugangsdaten, beide in ~/.config/emdash/auth.json (unter Berücksichtigung von XDG_CONFIG_HOME), erstellt mit nur-Eigentümer-Berechtigungen (0600):
- Site-Tokens —
emdash loginauthentifiziert gegen Ihre EmDash-Instanz über einen OAuth-Device-Flow und speichert das resultierende Token nach Instanz-URL.emdash logoutentfernt es; pro Aufruf überschreiben--tokenoderEMDASH_TOKENdas gespeicherte Token. - Marketplace-Tokens —
emdash plugin publishauthentifiziert beim EmDash Marketplace über einen GitHub-Device-Flow und speichert das resultierende JWT untermarketplace:<origin>. Für CI-Veröffentlichung setzen Sie stattdessenEMDASH_MARKETPLACE_TOKEN— es hat Vorrang vor dem gespeicherten Credential.
Der Verlust der Datei ist harmlos: führen Sie emdash login (oder emdash plugin publish, das den Device-Flow erneut ausführt) erneut aus.
Plugin-Register-CLI-Zugangsdaten
Die separate emdash-plugin-CLI (Paket @emdash-cms/plugin-cli) zielt auf das experimentelle AT-Protocol-Register. Das Veröffentlichen dort ist an Ihre AT-Protocol-Identität (Ihre Publisher-DID) gebunden — die Site selbst hält keine Veröffentlichungs-Zugangsdaten, und Installationen prüfen Artefakte gegen Prüfsummen aus Release-Records, die dieser DID zugeschrieben sind.
- Sie authentifiziert über atproto OAuth. Die OAuth-Session-/State-Blobs liegen in
~/.emdash/oauth/, und die Publisher-Identität (DID, Handle, PDS) wird in~/.emdash/credentials.jsonzwischengespeichert; beide werden mit nur-Eigentümer-Berechtigungen geschrieben. - In CI stellen Sie die Identität über
EMDASH_PUBLISHER_DID,EMDASH_PUBLISHER_HANDLEundEMDASH_PUBLISHER_PDSbereit;EMDASH_REGISTRY_URLüberschreibt den Register-Host. Automatisiertespublishaus CI braucht weiterhin die OAuth-Session-Dateien in~/.emdash/oauth/auf dem Runner — die Env-Variablen allein tragen die OAuth-Session nicht. - Das Rotieren oder Widerrufen von Veröffentlichungszugriff geschieht bei Ihrem AT-Protocol-Konto (z. B. App-Passwörter), nicht in EmDash. Siehe Atmosphere-Auth.
Rotations-Schnellreferenz
| Ich möchte… | Tun Sie dies |
|---|---|
| Plugin-Einstellungs-Verschlüsselung rotieren | Neuen Schlüssel voranstellen, Plugin-Geheimnisse erneut speichern, dann alten Schlüssel entfernen |
| Alle Preview-Links ungültig machen | Zeile emdash:preview_secret löschen (oder Env-Override ändern) |
| Kommentar-Rate-Limit-Hashing zurücksetzen | EMDASH_IP_SALT ändern (oder Zeile emdash:ip_salt löschen) |
| Ein geleaktes API-Token widerrufen | Admin → Users → API tokens → widerrufen, dann Ersatz erstellen |
| Alle Sessions beenden | Session-Store leeren (Workers-KV-Namespace / Session-Verzeichnis) |
| Eine Anbieter-Zugangsdaten ersetzen | Beim Anbieter rotieren, Env-Variable aktualisieren, neu deployen |
| Einen Plugin-API-Schlüssel ersetzen | Beim Anbieter rotieren, in den Admin-Einstellungen des Plugins erneut eingeben |