EmDash verwendet Passkey-Authentifizierung als primäre Anmeldemethode. Passkeys sind phishing-resistent, erfordern keine Passwörter und funktionieren geräteübergreifend über Ihren Browser oder Passwort-Manager.
Über Passkeys hinaus können Sie erweiterbare Login-Anbieter hinzufügen. GitHub und Google sind in EmDash enthalten. Der separat installierte Atmosphere-Anbieter fügt AT-Protocol-Konten hinzu, und dieselbe Anbieterschnittstelle ist für andere Pakete offen. Die dokumentierten GitHub-, Google- und Atmosphere-Anbieter können das erste Admin-Konto erstellen oder einen verknüpften EmDash-Benutzer anmelden.
Für Cloudflare-Deployments ist Cloudflare Access ein separater, exklusiver Authentifizierungsmodus in der Produktion. Er validiert Access-Anmeldedaten auf geschützten EmDash-Routen, anstatt die EmDash-Anmeldemethoden anzuzeigen.
Wählen Sie einen Authentifizierungsmodus
Passkeys verwenden WebAuthn, einen Webstandard, der Public-Key-Anmeldedaten erstellt, die auf Ihrem Gerät gespeichert oder über Ihren Passwort-Manager synchronisiert werden. Beim Anmelden beweist Ihr Gerät den Besitz der Anmeldedaten, ohne jemals ein Passwort über das Netzwerk zu senden.
Passkeys sind der Standard. GitHub-, Google- und Atmosphere-Anbieter sind zusätzliche Anmeldemethoden: Jeder authentifiziert den Benutzer, verknüpft oder erstellt ein EmDash-Konto und richtet dieselbe EmDash-Sitzung ein, die auch von einer Passkey-Anmeldung verwendet wird.
Passkey-Authentifizierung bietet:
- Keine Passwörter zum Merken oder Leaken
- Phishing-resistent — Anmeldedaten sind an die Domain Ihrer Website gebunden
- Geräteübergreifende Synchronisierung — funktioniert mit iCloud Keychain, Google Passwort-Manager, 1Password usw.
- Schnelle Anmeldung — ein Tippen mit Biometrie oder PIN
Cloudflare Access verwendet die auth-Option anstelle von authProviders. In der Produktion wird es zur Autorität für geschützte /_emdash-Routen. EmDash speichert weiterhin einen lokalen Benutzer, damit Rollen, Eigentümerschaft und Prüfungen auf deaktivierte Benutzer weiterhin funktionieren.
Den ersten Benutzer einrichten
Beim ersten Zugriff auf das Admin-Panel führt Sie der Setup-Assistent durch die Erstellung Ihres Admin-Kontos.
-
Navigieren Sie zu
http://localhost:4321/_emdash/admin -
Geben Sie auf Set up your site den Seitentitel und optionalen Slogan ein. Eine Vorlage kann auch Beispielinhalte anbieten. Wählen Sie Continue.
-
Geben Sie auf Create your account Ihre E-Mail-Adresse und einen optionalen Namen ein. Wählen Sie Continue.
-
Erstellen Sie auf Secure your account einen Passkey oder wählen Sie einen der konfigurierten Login-Anbieter. Wenn Sie einen Passkey wählen, fragt Ihr Browser, wo er gespeichert werden soll:
- Auf macOS: Touch ID, Gerätepasswort oder Sicherheitsschlüssel
- Auf Windows: Windows Hello oder Sicherheitsschlüssel
- Auf Mobilgeräten: Face ID, Fingerabdruck oder PIN
-
Schließen Sie den Browser- oder Anbieterfluss ab. EmDash erstellt den ersten Benutzer als Admin und öffnet das Dashboard.
Mit einem Passkey anmelden
Nach der Einrichtung löst die Rückkehr zum Admin-Panel die Passkey-Authentifizierung aus:
-
Besuchen Sie
/_emdash/admin -
Wenn Sie nicht angemeldet sind, sehen Sie die Login-Seite
-
Klicken Sie auf Sign in zum Authentifizieren
-
Ihr Browser fordert Ihren Passkey an (Biometrie, PIN oder Sicherheitsschlüssel)
-
Nach der Verifizierung werden Sie zum Admin-Dashboard weitergeleitet
Mit einem Magic Link anmelden
Wenn Sie Ihren Passkey nicht verwenden können, bietet ein Magic Link eine Alternative. Die Website muss einen E-Mail-Anbieter konfiguriert haben, bevor EmDash den Link senden kann.
-
Klicken Sie auf der Login-Seite auf Sign in with email
-
Geben Sie Ihre E-Mail-Adresse ein
-
Prüfen Sie Ihren Posteingang auf einen Login-Link
-
Klicken Sie auf den Link zum Authentifizieren (15 Minuten gültig)
Login-Anbieter konfigurieren
Zusätzlich zu Passkeys unterstützt EmDash erweiterbare Login-Anbieter, die auf der Login-Seite und im Setup-Assistenten erscheinen. GitHub und Google sind in EmDash enthalten. Atmosphere- und Drittanbieter sind separate Pakete, die sich über dieselbe Schnittstelle registrieren.
Anbieter sind additiv — Passkeys funktionieren weiterhin, wenn Anbieter aktiviert sind. GitHub und Google verknüpfen automatisch einen bestehenden EmDash-Benutzer nur, wenn der Anbieter dieselbe verifizierte E-Mail-Adresse liefert. Atmosphere-Konten werden über ihren dezentralen Identifikator (DID) verknüpft, da EmDashs Atmosphere-Fluss keine E-Mail-Adresse erhält. Jeder enthaltene Anbieter kann den ersten Benutzer erstellen, sodass eine Neuinstallation Passkeys komplett überspringen kann.
Anbieter zu Astro hinzufügen
Übergeben Sie Anbieter an das authProviders-Array in der EmDash-Integration. Das folgende Beispiel aktiviert GitHub, Google und Atmosphere:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { github } from "emdash/auth/providers/github";
import { google } from "emdash/auth/providers/google";
import { atproto } from "@emdash-cms/auth-atproto";
export default defineConfig({
integrations: [
emdash({
authProviders: [github(), google(), atproto()],
}),
],
});
Die Reihenfolge ist wichtig für die Login-Seite: Anbieter werden in der aufgelisteten Reihenfolge gerendert, mit kompakten Button-only-Anbietern zuerst und Anbietern, die ein benutzerdefiniertes Formular benötigen (wie Atmosphere, das nach einem Handle fragt), danach.
GitHub
Das folgende Beispiel aktiviert den GitHub-Anbieter:
import { github } from "emdash/auth/providers/github";
emdash({ authProviders: [github()] });
Legen Sie Anmeldedaten über Umgebungsvariablen fest. EmDash prüft zuerst die Namen mit Präfix und fällt auf die ohne Präfix zurück:
| Variable | Zweck |
|---|---|
EMDASH_OAUTH_GITHUB_CLIENT_ID / GITHUB_CLIENT_ID | OAuth-App Client-ID |
EMDASH_OAUTH_GITHUB_CLIENT_SECRET / GITHUB_CLIENT_SECRET | OAuth-App Secret |
Konfigurieren Sie die Callback-URL Ihrer GitHub OAuth-App als https://your-site.example.com/_emdash/api/auth/oauth/github/callback.
Das folgende Beispiel aktiviert den Google-Anbieter:
import { google } from "emdash/auth/providers/google";
emdash({ authProviders: [google()] });
Legen Sie Anmeldedaten über Umgebungsvariablen fest. EmDash prüft zuerst die Namen mit Präfix und fällt auf die ohne Präfix zurück:
| Variable | Zweck |
|---|---|
EMDASH_OAUTH_GOOGLE_CLIENT_ID / GOOGLE_CLIENT_ID | OAuth-App Client-ID |
EMDASH_OAUTH_GOOGLE_CLIENT_SECRET / GOOGLE_CLIENT_SECRET | OAuth-App Secret |
Konfigurieren Sie die Redirect-URI Ihres Google OAuth-Clients als https://your-site.example.com/_emdash/api/auth/oauth/google/callback.
Atmosphere (AT Protocol)
Für Websites, deren Beitragende bereits ein Atmosphere-Konto haben — die benutzergesteuerte Identität hinter Bluesky und dem breiteren AT-Protocol-Netzwerk — installieren Sie den Atmosphere-Anbieter:
pnpm add @emdash-cms/auth-atproto
Das folgende Beispiel aktiviert den Atmosphere-Anbieter mit einer Handle-Allowlist:
import { atproto } from "@emdash-cms/auth-atproto";
emdash({
authProviders: [
atproto({
allowedHandles: ["*.example.com"],
}),
],
});
Kein Client-Secret oder Umgebungsvariable erforderlich. Siehe den Atmosphere-Login-Leitfaden für Handle/DID-Allowlists, Rollenzuordnung und das lokale Entwicklungssetup, das das AT-Protocol-OAuth-Profil erfordert.
Einen Anbieter erstellen
Ein Anbieter ist ein AuthProviderDescriptor: eine id, ein menschenlesbares Label und die Admin-Komponenten, Route-Handler, öffentlichen Route-Präfixe und Speichersammlungen, die sein Login-Fluss benötigt. Exportieren Sie einen SetupStep aus adminEntry, wenn der Anbieter während der Erstbenutzer-Einrichtung erscheinen soll. Die Form wird aus emdash exportiert:
import type { AuthProviderDescriptor } from "emdash";
export function myProvider(): AuthProviderDescriptor {
return {
id: "my-provider",
label: "My Provider",
adminEntry: "my-provider/admin", // exportiert LoginButton / LoginForm / SetupStep
routes: [
{ pattern: "/_emdash/api/auth/my-provider/login", entrypoint: "my-provider/routes/login.ts" },
{ pattern: "/_emdash/api/auth/my-provider/callback", entrypoint: "my-provider/routes/callback.ts" },
],
publicRoutes: ["/_emdash/api/auth/my-provider/"],
storage: {
sessions: {},
},
};
}
Das Atmosphere-Paket (@emdash-cms/auth-atproto) ist die vollständigste reale Referenz für einen Anbieter, der ein benutzerdefiniertes Login-Formular, OAuth-Route-Handler und persistenten Speicher benötigt.
Benutzerrollen
EmDash verwendet rollenbasierte Zugriffskontrolle mit fünf Stufen:
| Rolle | Stufe | Beschreibung |
|---|---|---|
| Subscriber | 10 | Veröffentlichte Inhalte lesen (kein Entwurfszugriff) |
| Contributor | 20 | Inhalte erstellen (benötigt Genehmigung zur Veröffentlichung) |
| Author | 30 | Eigene Inhalte erstellen/bearbeiten/veröffentlichen |
| Editor | 40 | Alle Inhalte verwalten |
| Admin | 50 | Vollzugriff einschließlich Einstellungen |
Jede Rolle erbt Berechtigungen von allen niedrigeren Stufen. Der erste Benutzer wird immer als Admin erstellt.
Subscriber und Entwurfsinhalte
Subscriber besitzen die content:read-Berechtigung, damit mitgliederbeschränkte veröffentlichte Inhalte an authentifizierte Leser ausgeliefert werden können. Sie können keine Entwürfe, geplanten Elemente, gelöschte Elemente, Revisionen oder Vorschau-URLs sehen — diese sind durch content:read_drafts geschützt, das Contributor und höher gewährt wird. Die List- und Get-Endpunkte filtern transparent auf status=published für Subscriber; Nur-Editor-Ansichten (/compare, /revisions, /trash, /preview-url) lehnen Subscriber-Anfragen direkt ab.
Benutzer einladen
Admins können neue Benutzer über das Admin-Panel einladen:
-
Gehen Sie zu Settings > Users
-
Klicken Sie auf Invite User
-
Geben Sie die E-Mail des Benutzers ein und wählen Sie eine Rolle
-
Klicken Sie auf Send Invite
-
Wenn E-Mail konfiguriert ist, sendet EmDash die Einladung. Andernfalls kopieren Sie den generierten Link und senden ihn selbst an den Benutzer.
-
Der Benutzer öffnet den Link und erstellt das Konto mit einem Passkey oder einem Login-Anbieter, der auf der Einladungsseite angeboten wird.
Einladungslinks sind einmalig verwendbar und verfallen nach 7 Tagen.
Passkeys verwalten
Benutzer können ihre Passkeys in den Kontoeinstellungen verwalten:
- Passkey hinzufügen — Zusätzliche Passkeys als Backup oder für andere Geräte registrieren
- Passkey entfernen — Nicht mehr verwendete Passkeys löschen
- Passkey umbenennen — Passkeys beschreibende Namen geben
Jeder Benutzer kann bis zu 10 Passkeys registriert haben.
EmDash erlaubt es einem Benutzer nicht, seinen letzten Passkey zu entfernen. Fügen Sie einen Ersatz hinzu, bevor Sie den alten löschen.
Eine Gruppe ohne Einladungen anmelden lassen
Um einer Gruppe die Anmeldung ohne einzelne Einladungen zu ermöglichen, konfigurieren Sie einen Login-Anbieter mit einer Allowlist. Der Atmosphere-Anbieter akzeptiert allowedHandles und allowedDIDs (siehe Atmosphere-Login); der Cloudflare Access-Adapter provisioniert Benutzer von Ihrem Identitätsanbieter über autoProvision und roleMapping. Die dokumentierten GitHub-, Google- und Atmosphere-Anbieter können auch das erste Admin-Konto erstellen.
Sitzungen
Passkey-, Magic-Link-, Einladungs- und Login-Anbieter-Callbacks speichern die EmDash-Benutzer-ID in Astros Session-Store. Der Browser erhält Astros opaken astro-session-Identifikator; Benutzer- und Anmeldedatensätze verbleiben in der EmDash-Datenbank.
Cloudflare Access schreibt ebenfalls den aufgelösten EmDash-Benutzer in die Astro-Sitzung. Das ermöglicht öffentlichen Seiten, einen angemeldeten Benutzer zu identifizieren, wenn sie Astro.locals.user lesen. Die Sitzung ersetzt nicht die Access-Authentifizierung auf geschützten /_emdash-Routen: EmDash validiert das Access JSON Web Token (JWT) bei diesen Anfragen erneut.
Authentifizierungs-Ratenlimits
EmDash begrenzt die Endpunkte, die unauthentifizierte Login- oder Registrierungsflüsse starten. Die Limits gelten separat für jeden Endpunkt und jede vertrauenswürdige Client-IP:
| Endpunkt | Limit |
|---|---|
POST /_emdash/api/auth/passkey/options | 10 Anfragen pro Minute |
POST /_emdash/api/auth/magic-link/send | 3 Anfragen pro 5 Minuten |
POST /_emdash/api/auth/signup/request | 3 Anfragen pro 5 Minuten |
Auf Cloudflare liest EmDash die Client-IP aus Cloudflares Anfragemetadaten. Eine selbst gehostete Website hinter einem Reverse-Proxy muss trustedProxyHeaders konfigurieren, bevor EmDash den Client-IP-Header des Proxys verwenden kann. Wenn keine vertrauenswürdige IP verfügbar ist, werden diese Pro-IP-Prüfungen übersprungen, da es keinen sicheren Schlüssel zum Zählen gibt.
Passkeys speichern Public-Key-Anmeldedaten; der private Schlüssel verbleibt beim Authenticator des Benutzers. Magic-Link-Token werden als SHA-256-Hashes gespeichert und nach Verwendung gelöscht.
Fehlerbehebung
”No passkeys registered”
Wenn Sie diesen Fehler bei der Anmeldung sehen, wurde Ihr Passkey möglicherweise aus Ihrem Passwort-Manager gelöscht. Bitten Sie einen Admin, einen Wiederherstellungs-Magic-Link zu senden; die Website muss E-Mail konfiguriert haben.
”Passkey authentication failed”
Dies bedeutet normalerweise, dass der Passkey für eine andere Domain erstellt wurde. Passkeys sind domaingebunden — ein Passkey für localhost:4321 funktioniert nicht auf example.com. Registrieren Sie einen neuen Passkey für jede Domain.
Alle Passkeys verloren
Wenn Sie den Zugang zu allen registrierten Passkeys verloren haben:
- Bitten Sie einen anderen Admin, einen Wiederherstellungs-Magic-Link zu senden. Die Website muss E-Mail konfiguriert haben.
- Verwenden Sie den Link innerhalb von 15 Minuten zum Anmelden.
- Registrieren Sie einen neuen Passkey in den Kontoeinstellungen.
Wenn Sie der einzige Admin sind und E-Mail nicht konfiguriert ist, müssen Sie die Authentifizierung Ihrer Website über die Datenbank zurücksetzen.
Cloudflare Access
Beim Deployment auf Cloudflare können Sie Cloudflare Access anstelle der eingebauten Anmeldemethoden verwenden. Access authentifiziert den Benutzer am Edge mit Ihrem Identitätsanbieter. EmDash validiert das signierte Access-JWT, lädt die Identität und Gruppen der Person und ordnet diese Identität einem lokalen EmDash-Benutzer zu.
Wann Cloudflare Access verwenden
- Single Sign-On — Benutzer authentifizieren sich mit dem IdP Ihres Unternehmens
- Zentralisierte Zugriffskontrolle — Verwalten Sie im Cloudflare-Dashboard, wer auf das Admin zugreifen kann
- Kein Passkey-Management — Keine Notwendigkeit, Passkeys zu registrieren oder zu verwalten
- Gruppenbasierte Rollen — IdP-Gruppen automatisch auf EmDash-Rollen abbilden
Access einrichten
- Erstellen Sie eine Cloudflare-Access-Anwendung und -Richtlinie für den
/_emdash/*-Pfad Ihrer Website. Nur/_emdash/admin/*zu schützen lässt die REST-API ohne das JWT, das EmDash erwartet. - Kopieren Sie das Application Audience (AUD) Tag der Anwendung.
- Speichern Sie das Tag in der Laufzeit-Umgebungsvariable
CF_ACCESS_AUDIENCE. Folgen Sie dem EmDash Secrets-Leitfaden für lokale und bereitgestellte Werte. - Konfigurieren Sie EmDash, um diesen Wert zur Laufzeit zu lesen:
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import emdash from "emdash/astro";
import { d1, access } from "@emdash-cms/cloudflare";
export default defineConfig({
output: "server",
adapter: cloudflare(),
integrations: [
emdash({
database: d1({ binding: "DB" }),
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audienceEnvVar: "CF_ACCESS_AUDIENCE",
}),
}),
],
});
Die Application Audience identifiziert, welche Access-Anwendung das JWT ausgestellt hat. EmDash verifiziert sie zusammen mit dem Aussteller und der Signatur; ein Token für eine andere Access-Anwendung wird abgelehnt.
Konfigurationsoptionen
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
teamDomain | string | erforderlich | Ihre Access Team-Domain (z.B. myteam.cloudflareaccess.com) |
audience | string | — | Application Audience (AUD) Tag direkt angegeben. Bevorzugen Sie audienceEnvVar auf Workers. |
autoProvision | boolean | true | EmDash-Benutzer beim ersten Access-Login erstellen |
defaultRole | number | 30 | Rolle für Benutzer, die keiner Gruppe zugeordnet werden (30 = Author) |
syncRoles | boolean | false | Rolle bei jedem Login basierend auf IdP-Gruppen aktualisieren |
roleMapping | object | — | IdP-Gruppennamen auf Rollenstufen abbilden |
audienceEnvVar | string | "CF_ACCESS_AUDIENCE" | Umgebungsvariable mit dem Audience-Tag. Wird verwendet, wenn audience weggelassen wird. |
Geben Sie entweder audience oder einen Umgebungswert unter audienceEnvVar an.
Rollenzuordnung
Ordnen Sie Ihre IdP-Gruppen EmDash-Rollen zu:
emdash({
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audienceEnvVar: "CF_ACCESS_AUDIENCE",
roleMapping: {
Admins: 50, // Admin
"Content Editors": 40, // Editor
Writers: 30, // Author
},
defaultRole: 20, // Contributor für Benutzer in keiner Gruppe
}),
});
Die erste übereinstimmende Gruppe gewinnt, wenn ein Benutzer mehreren Gruppen angehört. Der erste Benutzer, der die Website besucht, wird immer Admin, unabhängig von Gruppen.
Rollensynchronisierungsverhalten
Standardmäßig (syncRoles: false) wird die Rolle eines Benutzers bei der ersten Anmeldung festgelegt und ändert sich danach nicht. Dies ermöglicht Admins, Rollen in EmDash manuell anzupassen.
Setzen Sie syncRoles: true, wenn IdP-Gruppen maßgebend sein sollen — die Rolle des Benutzers wird bei jeder Anmeldung basierend auf seinen aktuellen Gruppen aktualisiert.
Anfrage- und Sitzungsfluss
- Der Benutzer besucht einen durch die Access-Anwendung geschützten Pfad.
- Cloudflare Access leitet den Benutzer zu Ihrem Identitätsanbieter um, wenn keine Access-Sitzung existiert.
- Nach der Authentifizierung sendet Access ein signiertes JWT an den Origin in
Cf-Access-Jwt-Assertion. - EmDash validiert die Signatur, den Aussteller und die Audience des Tokens und liest dann die Access-Identität und -Gruppen.
- EmDash findet oder provisioniert den lokalen Benutzer, wendet das konfigurierte Rollenverhalten an und zeichnet den Benutzer in der Astro-Sitzung auf.
- Spätere Anfragen an geschützte EmDash-Routen wiederholen die Access-Validierung. Öffentliche Seiten können die EmDash-Sitzung nutzen, um den Benutzer zu identifizieren, ohne sie als Beweis für eine neue Access-Anfrage zu behandeln.
Durch Access ersetzte Funktionen
Wenn Access aktiviert ist, sind diese Funktionen nicht verfügbar:
- Login-Seite (
/_emdash/admin/login) - Passkey-Registrierung und -Verwaltung
- GitHub-, Google- und Atmosphere-Login
- Magic-Link-Login
- Selbstregistrierung
- Benutzereinladungen
Access-Richtlinien entscheiden, wer EmDash erreicht. EmDash besitzt weiterhin lokale Rollen, Inhaltseigentümerschaft und das Deaktiviert-Flag. Mit syncRoles: false können Administratoren die Rolle eines provisionierten Benutzers in EmDash ändern. Mit syncRoles: true ersetzen die zugeordneten Access-Gruppen diese Rolle bei jeder Anmeldung.
Fehlerbehebung
”No Access JWT present”
Die Anfrage erreichte EmDash ohne Access-JWT. Das bedeutet:
- Access ist nicht konfiguriert, um Ihre Anwendung zu schützen
- Die Access-Richtlinie stimmt nicht mit den Admin-Routen überein
Überprüfen Sie, dass die Access-Anwendung den vollständigen /_emdash/*-Pfad abdeckt und dass ihre Richtlinie den Benutzer einschließt.
”JWT audience mismatch”
Die audience in Ihrer Konfiguration stimmt nicht mit dem JWT überein. Überprüfen Sie das Application Audience Tag in Ihren Access-Anwendungseinstellungen.
”User not authorized”
Der Benutzer hat sich über Access authentifiziert, aber autoProvision ist false und er existiert nicht in EmDash. Entweder:
- Setzen Sie
autoProvision: true, oder - Erstellen Sie den Benutzer manuell, bevor er sich anmeldet