Anhand dieser Übersicht entscheiden Sie, welche Werte in die Laufzeitumgebung gehören, welche in der Datenbank generiert werden und welche von Plugins gespeichert werden. Jeder Abschnitt beschreibt, wie sich eine Rotation auf eine laufende Site auswirkt.
Legen Sie unter Node.js Laufzeit-Geheimnisse im Secret-Manager der Hosting-Plattform ab, damit sie beim Start des Prozesses in process.env landen. Verwenden Sie für einen Worker wrangler secret put. Legen Sie keine geheimen Werte in astro.config.mjs, wrangler.jsonc oder import.meta.env ab; Vite kann Werte zur Build-Zeit in das Server-Bundle einbetten.
Übersicht
| Geheimnis | Quelle | Gespeichert in | Auswirkung bei verlorenem Schlüssel |
|---|---|---|---|
EMDASH_ENCRYPTION_KEY | Betreiber (emdash secrets generate) | Nur Umgebung / Worker-Secret | Verschlüsselte Plugin-Einstellungen sind unlesbar, bis der passende Schlüssel wiederhergestellt ist |
| Preview-Geheimnis | Automatisch generiert (Überschreiben per Umgebungsvariable) | Tabelle options (emdash:preview_secret) | Bereits ausgegebene Preview-Links funktionieren nicht mehr; neue sind unproblematisch |
| IP-Salt | Automatisch generiert (Überschreiben per Umgebungsvariable) | Tabelle options (emdash:ip_salt) | Die Kontinuität des Kommentar-Ratenlimits wird zurückgesetzt |
| Session- und API-Tokens | Pro Session/Token generiert | Session-Store / Datenbank (nur Hashes) | Keine — der Klartext wird nie gespeichert |
| OAuth-Provider-Zugangsdaten | Sie (Google, GitHub oder Microsoft-Entra-Konsole) | Umgebung | Die Anmeldung über diesen Provider ist unterbrochen, bis die Zugangsdaten ersetzt sind |
| Turnstile-Geheimnis | Sie (Cloudflare-Dashboard) | Umgebung | Die CAPTCHA-Prüfung für Kommentare schlägt fehl |
| S3-Zugangsdaten | Sie (Speicher-Provider) | Laufzeitumgebung | Medien-Upload/-Download schlägt fehl, bis die Zugangsdaten ersetzt sind |
| Plugin-Geheimnisse | Sie (Einstellungsoberfläche im Admin) | Verschlüsselte Datenbankeinstellung | Passenden Verschlüsselungsschlüssel wiederherstellen oder den Wert erneut eingeben |
| CLI-Zugangsdaten | emdash login-Device-Flow | ~/.config/emdash/auth.json (Modus 0600) | Den Device-Flow erneut ausführen |
| Registry-CLI-Zugangsdaten | emdash-plugin atproto-OAuth | ~/.emdash/oauth/, ~/.emdash/credentials.json (Modus 0600) | Erneut anmelden; die 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, wobei Plugin-ID und Einstellungsschlüssel als authentifizierte Daten dienen. Ein fehlerhafter Wert erzeugt eine an den Betreiber gerichtete Startmeldung, und Vorgänge, die verschlüsselte Plugin-Einstellungen benötigen, schlagen geschlossen fehl (Fail-Closed). Davon unabhängige Site-Anfragen funktionieren weiterhin.
Der folgende Befehl erzeugt einen korrekt formatierten Wert. Legen Sie ihn in der Laufzeitumgebung oder als Worker-Secret ab, wenn Ihr Deployment diese Variable verwendet.
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 base64url ohne Padding. 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 den alten Wert hinter einem Komma bei:
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. Zum Lesen wählt es anhand des gespeicherten kid-Fingerabdrucks einen älteren Schlüssel aus. Speichern Sie jedes Plugin-Geheimnis erneut, bevor Sie den alten Schlüssel entfernen, und prüfen Sie diese Integrationen anschließend mit einem Deployment, das nur den neuen Schlüssel enthält. EmDash meldet derzeit nicht, welche Schlüssel-IDs noch in Gebrauch sind. Führen Sie daher eine Liste der Zugangsdaten, die Sie erneut speichern, und entfernen Sie einen alten Schlüssel erst, wenn jede Integration diese Prüfung bestanden hat.
Generierte Site-Geheimnisse
Zwei Geheimnisse werden bei der ersten Verwendung automatisch generiert und in der Tabelle options persistiert, sodass sie über Anfragen, Deployments und Isolates hinweg stabil sind. Die Generierung ist atomar — gleichzeitige Kaltstarts konvergieren auf einen einzigen Wert.
Preview-Geheimnis
Signiert Preview-URLs (HMAC). Gespeichert als emdash:preview_secret; 32 Zufallsbytes, base64url.
- Überschreiben: Setzen Sie
EMDASH_PREVIEW_SECRET(veralteter Alias:PREVIEW_SECRET), wenn Sie dasselbe Geheimnis über mehrere Prozesse hinweg benötigen oder es aus Audit-Gründen festschreiben möchten. Die Umgebung hat immer Vorrang vor dem gespeicherten Wert. - Rotation: Löschen Sie die Zeile
emdash:preview_secret(oder ändern Sie die Umgebungsvariable) und deployen Sie erneut. Auswirkung: Zuvor ausgegebene Preview-Links werden nicht mehr validiert. Sonst geht nichts kaputt — bei der nächsten Preview-Anfrage wird ein neues Geheimnis generiert (oder aus der Umgebung gelesen). - Bei Verlust: Nichts ist unwiederbringlich. Preview-Links sind von Haus aus kurzlebig.
Wie Preview-URLs aufgebaut und verifiziert werden, steht im Preview-Leitfaden.
IP-Salt
Salzt den SHA-256-Hash der IP-Adressen von Kommentierenden (ip_hash bei Kommentaren), der für das Ratenlimit bei Kommentaren verwendet wird. Gespeichert als emdash:ip_salt. Es ist site-spezifisch, sodass Hashes über EmDash-Installationen hinweg nicht korrelierbar sind.
- Überschreiben: Setzen Sie
EMDASH_IP_SALT. Aus Gründen der Abwärtskompatibilität werden auchEMDASH_AUTH_SECRET/AUTH_SECRETberücksichtigt — Installationen, die das Salt historisch daraus abgeleitet haben, behalten stabile Hashes. - Rotation: Ändern Sie die Umgebungsvariable oder löschen Sie die Zeile
emdash:ip_saltund deployen Sie anschließend erneut. Auswirkung: Neue Kommentareinreichungen erzeugen andere Hashes, sodass die Ratenlimit-Zählung für alle neu beginnt. Bestehende Kommentare und ihre gespeicherten Hashes bleiben unberührt. - Bei Verlust: Kein Datenverlust. Nur die Kontinuität des Ratenlimits wird zurückgesetzt.
Session- und API-Tokens
- Sessions nutzen den Session-Store von Astro (Workers KV auf Cloudflare, Dateisystem auf Node). Adapter, die keinen Store konfigurieren, etwa Vercel, benötigen in
astro.config.mjseinen Session-Driver; ohne einen solchen schlägt die Anmeldung mit einem Fehler fehl, der erklärt, dass ein Session-Driver erforderlich ist. Das Cookie enthält eine undurchsichtige Session-ID; es gibt kein Signing-Geheimnis, das verwaltet werden müsste. Melden Sie sich ab, um eine Session zu beenden, oder leeren Sie den Session-Store (z. B. den KV-Namespace), um alle zur erneuten Anmeldung zu zwingen. - 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 einmalig bei der Erstellung angezeigt. Rotieren Sie, indem Sie das Token im Admin widerrufen und neu erstellen. - Einladungs-, Magic-Link- und Wiederherstellungs-Tokens haben jeweils einen einzigen Zweck, werden als SHA-256-Hashes in
auth_tokensgespeichert und sind zeitlich begrenzt (Einladungen 7 Tage, Magic Links 15 Minuten).
Es gibt nichts, was Sie vorsorglich sichern oder rotieren müssten: Ein Datenbank-Leak legt nur Hashes offen, und jedes Token lässt sich im Admin widerrufen oder neu ausstellen.
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 Provider, aktualisieren Sie die Variable und deployen Sie erneut.
| Dienst | Variablen |
|---|---|
| Google-Anmeldung | EMDASH_OAUTH_GOOGLE_CLIENT_ID, EMDASH_OAUTH_GOOGLE_CLIENT_SECRET (oder Aliase ohne Präfix) |
| GitHub-Anmeldung | EMDASH_OAUTH_GITHUB_CLIENT_ID, EMDASH_OAUTH_GITHUB_CLIENT_SECRET (oder Aliase ohne Präfix) |
| Microsoft-Anmeldung | EMDASH_OAUTH_MICROSOFT_CLIENT_ID, EMDASH_OAUTH_MICROSOFT_CLIENT_SECRET, EMDASH_OAUTH_MICROSOFT_TENANT_ID (oder Aliase ohne Präfix) |
| 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 |
Setzen Sie diese auf Cloudflare mit wrangler secret put; legen Sie sie für die lokale Entwicklung in .env ab. Wrangler liest entweder .dev.vars oder .env, nicht beides, und .dev.vars hat Vorrang, wenn vorhanden. R2 über ein Binding benötigt keine Zugriffsschlüssel-Variablen, da das Binding den Laufzeitzugriff gewährt. Siehe Medienspeicher.
Unter Node liest EmDash den geheimen Turnstile-Schlüssel aus der Prozessumgebung des Servers, sobald eine Anfrage eintrifft, und weder astro dev noch der gebaute Server lädt .env in diese Umgebung. Setzen Sie den Schlüssel in der Umgebung Ihres Hosts, exportieren Sie ihn in der Shell, in der astro dev läuft, oder starten Sie den gebauten Server mit node --env-file=.env ./dist/server/entry.mjs.
Plugin-Geheimnisse
Einstellungen, die ein Plugin mit type: "secret" deklariert (API-Schlüssel für E-Mail-Provider, Formular-CAPTCHAs usw.), werden in der Admin-Oberfläche eingegeben und in der Tabelle options unter plugin:<id>:settings:<key> verschlüsselt gespeichert. Der Admin erhält nur die Information, ob ein Geheimnis gesetzt ist — auch dann, wenn der passende Verschlüsselungsschlüssel nicht verfügbar ist —, sodass ein Administrator unlesbare Zugangsdaten ersetzen kann. Plugin-Code liest den Klartext über ctx.settings innerhalb seiner isolierten Laufzeit. Werte, die außerhalb eines deklarierten Einstellungsschemas gespeichert werden, einschließlich beliebiger Plugin-KV- und Statuseinträge, nutzen diesen Verschlüsselungspfad nicht.
- Rotation von Zugangsdaten: Rotieren Sie die Zugangsdaten beim Provider und fügen Sie den neuen Wert auf der Einstellungsseite des Plugins ein. Beim Speichern wird ein neuer verschlüsselter Umschlag geschrieben.
- Migration von Klartext: 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 geht: Stellen Sie den passenden
EMDASH_ENCRYPTION_KEYaus dem separaten Schlüssel-Backup wieder her. Existiert keine Kopie, ersetzen Sie alle betroffenen Zugangsdaten beim jeweiligen Provider und geben Sie die Ersatzwerte ein, nachdem Sie einen neuen Verschlüsselungsschlüssel konfiguriert haben.
CLI-Zugangsdaten
Die emdash-CLI speichert Site-Tokens in ~/.config/emdash/auth.json (unter Beachtung von XDG_CONFIG_HOME) mit Berechtigungen nur für den Besitzer (0600). emdash login authentifiziert sich über einen OAuth-Device-Flow bei Ihrer EmDash-Instanz und speichert das Token, geschlüsselt nach Instanz-URL. emdash logout entfernt es; pro Aufruf überschreibt --token oder EMDASH_TOKEN das gespeicherte Token.
Der Verlust der Datei ist harmlos: Führen Sie emdash login einfach 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 Zugangsdaten zum Veröffentlichen, und Installationen verifizieren Artefakte anhand von Prüfsummen aus Release-Einträgen, die dieser DID zugeordnet sind.
- Die Authentifizierung erfolgt über atproto-OAuth. Die OAuth-Session-/Zustandsdaten liegen in
~/.emdash/oauth/, und die Publisher-Identität (DID, Handle, PDS) wird in~/.emdash/credentials.jsonzwischengespeichert; beides wird mit Berechtigungen nur für den Besitzer geschrieben. - Geben Sie die Identität in CI über
EMDASH_PUBLISHER_DID,EMDASH_PUBLISHER_HANDLEundEMDASH_PUBLISHER_PDSan;EMDASH_REGISTRY_URLüberschreibt den Register-Host. Ein automatisiertespublishaus CI benötigt weiterhin die OAuth-Sessiondateien in~/.emdash/oauth/auf dem Runner — die Umgebungsvariablen allein transportieren die OAuth-Session nicht. - Das Rotieren oder Widerrufen des Veröffentlichungszugriffs erfolgt bei Ihrem AT-Protocol-Konto (z. B. über App-Passwörter), nicht in EmDash. Siehe Atmosphere auth.
Rotations-Schnellreferenz
| Ich möchte … | So geht es |
|---|---|
| Die Verschlüsselung der Plugin-Einstellungen rotieren | Den neuen Schlüssel voranstellen, Plugin-Geheimnisse erneut speichern, dann den alten Schlüssel entfernen |
| Alle Preview-Links ungültig machen | Die Zeile emdash:preview_secret löschen (oder die Umgebungsvariable ändern), erneut deployen |
| Das Hashing des Kommentar-Ratenlimits zurücksetzen | EMDASH_IP_SALT ändern (oder die Options-Zeile emdash:ip_salt löschen), erneut deployen |
| Ein geleaktes API-Token widerrufen | Admin → Users → API tokens → widerrufen, dann ein Ersatz-Token erstellen |
| Alle Sessions beenden | Den Session-Store leeren (Workers-KV-Namespace / Session-Verzeichnis) |
| Zugangsdaten eines Providers ersetzen | Beim Provider rotieren, Umgebungsvariable aktualisieren, erneut deployen |
| Einen Plugin-API-Schlüssel ersetzen | Beim Provider rotieren, in den Admin-Einstellungen des Plugins erneut eingeben |