Authentification

Sur cette page

EmDash utilise l’authentification par passkey comme méthode de connexion principale. Les passkeys sont résistants au phishing, ne nécessitent pas de mots de passe et fonctionnent sur tous les appareils via votre navigateur ou gestionnaire de mots de passe.

Au-delà des passkeys, vous pouvez ajouter des fournisseurs de connexion interchangeables — GitHub, Google et l’Atmosphere (AT Protocol) sont fournis d’origine, et la même interface de fournisseur est ouverte aux packages tiers. Tout fournisseur configuré peut être utilisé pour créer le premier compte administrateur, se connecter ou se lier à un utilisateur existant.

Pour les déploiements Cloudflare, Cloudflare Access est également disponible en tant que méthode d’authentification exclusive qui prend en charge l’ensemble du flux de connexion.

Comment ça marche

Les passkeys utilisent WebAuthn, une norme web qui crée des identifiants à clé publique stockés sur votre appareil ou synchronisés via votre gestionnaire de mots de passe. Lorsque vous vous connectez, votre appareil prouve la possession de l’identifiant sans jamais envoyer de mot de passe sur le réseau.

Avantages de l’authentification par passkey :

  • Pas de mots de passe à retenir ou à fuiter
  • Résistant au phishing — les identifiants sont liés au domaine de votre site
  • Synchronisation entre appareils — fonctionne avec iCloud Keychain, Google Password Manager, 1Password, etc.
  • Connexion rapide — un toucher avec la biométrie ou le code PIN

Configuration du premier utilisateur

La première fois que vous accédez au panneau d’administration, l’Assistant de configuration vous guide dans la création de votre compte administrateur.

  1. Accédez à http://localhost:4321/_emdash/admin

  2. Vous serez redirigé vers l’Assistant de configuration. Entrez :

    • Titre du site — Le nom de votre site
    • Slogan — Une courte description
    • Email administrateur — Votre adresse e-mail
  3. Cliquez sur Créer le site pour enregistrer votre passkey

  4. Votre navigateur vous invitera à créer un passkey :

    • Sur macOS : Touch ID, mot de passe de l’appareil ou clé de sécurité
    • Sur Windows : Windows Hello ou clé de sécurité
    • Sur mobile : Face ID, empreinte digitale ou code PIN
  5. Une fois votre passkey enregistré, vous êtes connecté et redirigé vers le tableau de bord d’administration.

Se connecter

Après la configuration, le retour au panneau d’administration déclenche l’authentification par passkey :

  1. Visitez /_emdash/admin

  2. Si vous n’êtes pas connecté, vous verrez la page de connexion

  3. Cliquez sur Se connecter pour vous authentifier

  4. Votre navigateur demande votre passkey (biométrie, code PIN ou clé de sécurité)

  5. Après vérification, vous êtes redirigé vers le tableau de bord d’administration

Lien magique de secours

Si vous ne pouvez pas utiliser votre passkey (par exemple, appareil perdu), les liens magiques fournissent une alternative. Cela nécessite que l’e-mail soit configuré.

  1. Sur la page de connexion, cliquez sur Se connecter avec l’e-mail

  2. Entrez votre adresse e-mail

  3. Vérifiez votre boîte de réception pour un lien de connexion

  4. Cliquez sur le lien pour vous authentifier (valable 15 minutes)

Fournisseurs de connexion

En plus des passkeys, EmDash prend en charge les fournisseurs de connexion interchangeables qui apparaissent sur la page de connexion et dans l’assistant de configuration. Les fournisseurs GitHub, Google et Atmosphere sont inclus dans la boîte ; les packages tiers peuvent enregistrer les leurs en utilisant la même interface.

Les fournisseurs sont additifs — les passkeys continuent de fonctionner lorsque les fournisseurs sont activés, et les utilisateurs peuvent lier un fournisseur à un compte existant ne comportant que des passkeys. Le premier utilisateur peut également être créé via n’importe quel fournisseur configuré, de sorte qu’une nouvelle installation peut ignorer complètement les passkeys si vous préférez.

Configurer les fournisseurs

Passez les fournisseurs au tableau authProviders sur l’intégration EmDash. L’exemple suivant active GitHub, Google et 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()],
		}),
	],
});

L’ordre compte pour la page de connexion : les fournisseurs s’affichent dans l’ordre où vous les listez, avec les fournisseurs compacts à bouton uniquement en premier et les fournisseurs nécessitant un formulaire personnalisé (comme Atmosphere, qui demande un identifiant) affichés après.

GitHub

L’exemple suivant active le fournisseur GitHub :

import { github } from "emdash/auth/providers/github";

emdash({ authProviders: [github()] });

Définissez les identifiants via des variables d’environnement. EmDash vérifie d’abord les noms préfixés et revient aux non préfixés :

VariableObjectif
EMDASH_OAUTH_GITHUB_CLIENT_ID / GITHUB_CLIENT_IDID client de l’application OAuth
EMDASH_OAUTH_GITHUB_CLIENT_SECRET / GITHUB_CLIENT_SECRETSecret de l’application OAuth

Configurez l’URL de rappel de votre application OAuth GitHub comme https://your-site.example.com/_emdash/api/auth/oauth/github/callback.

Google

L’exemple suivant active le fournisseur Google :

import { google } from "emdash/auth/providers/google";

emdash({ authProviders: [google()] });

Définissez les identifiants via des variables d’environnement. EmDash vérifie d’abord les noms préfixés et revient aux non préfixés :

VariableObjectif
EMDASH_OAUTH_GOOGLE_CLIENT_ID / GOOGLE_CLIENT_IDID client de l’application OAuth
EMDASH_OAUTH_GOOGLE_CLIENT_SECRET / GOOGLE_CLIENT_SECRETSecret de l’application OAuth

Configurez l’URI de redirection de votre client OAuth Google comme https://your-site.example.com/_emdash/api/auth/oauth/google/callback.

Atmosphere (AT Protocol)

Pour les sites où les contributeurs ont déjà un compte Atmosphere — l’identité appartenant à l’utilisateur derrière Bluesky et le réseau AT Protocol plus large — installez le fournisseur Atmosphere :

pnpm add @emdash-cms/auth-atproto

L’exemple suivant active le fournisseur Atmosphere avec une liste d’identifiants autorisés :

import { atproto } from "@emdash-cms/auth-atproto";

emdash({
	authProviders: [
		atproto({
			allowedHandles: ["*.example.com"],
		}),
	],
});

Aucun secret client ou variable d’environnement n’est nécessaire. Consultez le guide de connexion Atmosphere pour les listes d’identifiants/DID autorisés, la correspondance des rôles et la configuration de développement local requise par le profil OAuth du protocole AT.

Créer votre propre fournisseur

Un fournisseur n’est qu’un AuthProviderDescriptor — un id, un label lisible et n’importe quelle combinaison de composants React côté administration, gestionnaires de routes, préfixes de routes publiques et collections de stockage. La forme est exportée depuis emdash :

import type { AuthProviderDescriptor } from "emdash";

export function myProvider(): AuthProviderDescriptor {
	return {
		id: "my-provider",
		label: "My Provider",
		adminEntry: "my-provider/admin", // exports 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: {},
		},
	};
}

Le package Atmosphere (@emdash-cms/auth-atproto) est la référence réelle la plus complète pour un fournisseur nécessitant un formulaire de connexion personnalisé, des gestionnaires de routes OAuth et un stockage persistant.

Rôles d’utilisateur

EmDash utilise un contrôle d’accès basé sur les rôles avec cinq niveaux :

RôleNiveauDescription
Subscriber10Lire le contenu publié (pas d’accès aux brouillons)
Contributor20Créer du contenu (nécessite une approbation pour publier)
Author30Créer/modifier/publier son propre contenu
Editor40Gérer tout le contenu
Admin50Accès complet y compris les paramètres

Chaque rôle hérite des permissions de tous les niveaux inférieurs. Le premier utilisateur est toujours créé en tant qu’Admin.

Abonnés et contenu brouillon

Les abonnés détiennent la permission content:read pour que le contenu publié réservé aux membres puisse être servi aux lecteurs authentifiés. Ils ne peuvent pas voir les brouillons, les éléments programmés, les éléments mis à la corbeille, les révisions ou les URL de prévisualisation — ceux-ci sont protégés par content:read_drafts, accordé aux Contributors et au-dessus. Les points de terminaison de liste et d’obtention filtrent de manière transparente vers status=published pour les Abonnés ; les vues réservées aux éditeurs (/compare, /revisions, /trash, /preview-url) rejettent les demandes des Abonnés directement.

Inviter des utilisateurs

Les administrateurs peuvent inviter de nouveaux utilisateurs via le panneau d’administration :

  1. Allez dans Paramètres > Utilisateurs

  2. Cliquez sur Inviter un utilisateur

  3. Entrez l’e-mail de l’utilisateur et sélectionnez un rôle

  4. Cliquez sur Envoyer l’invitation

  5. L’utilisateur reçoit un e-mail avec un lien d’invitation

  6. Il clique sur le lien et enregistre son passkey

Les invitations sont valables 7 jours. Les administrateurs peuvent renvoyer ou révoquer les invitations depuis la page Utilisateurs.

Gérer les passkeys

Les utilisateurs peuvent gérer leurs passkeys depuis les paramètres du compte :

  • Ajouter un passkey — Enregistrer des passkeys supplémentaires pour la sauvegarde ou d’autres appareils
  • Supprimer un passkey — Supprimer les passkeys que vous n’utilisez plus
  • Renommer un passkey — Donner des noms descriptifs aux passkeys

Chaque utilisateur peut avoir jusqu’à 10 passkeys enregistrés.

Permettre à un groupe de se connecter sans invitations

Pour permettre à un groupe de se connecter sans inviter chaque utilisateur, configurez un fournisseur de connexion avec une liste autorisée. Le fournisseur Atmosphere accepte allowedHandles et allowedDIDs (voir connexion Atmosphere); l’adaptateur Cloudflare Access provisionne les utilisateurs depuis votre fournisseur d’identité via autoProvision et roleMapping. Tout fournisseur configuré peut également créer le compte administrateur initial.

Sessions

Les sessions utilisent des cookies sécurisés, HttpOnly, SameSite=Lax et durent 30 jours avec expiration glissante — l’expiration se réinitialise avec l’activité.

Notes de sécurité

  • Les passkeys sont stockés en tant que clés publiques — la clé privée ne quitte jamais votre appareil
  • Vérification du défi empêche les attaques par rejeu
  • Limitation du débit protège contre la force brute (5 tentatives/minute/IP)
  • Les sessions sont HttpOnly, Secure, SameSite=Lax pour la sécurité des cookies
  • Les jetons de lien magique sont hachés SHA-256 — les jetons bruts ne sont jamais stockés

Dépannage

”Aucun passkey enregistré”

Si vous voyez cette erreur lors de la connexion, votre passkey a peut-être été supprimé de votre gestionnaire de mots de passe. Demandez à un administrateur de vous envoyer un lien magique ou une nouvelle invitation.

”Échec de l’authentification par passkey”

Cela signifie généralement que le passkey a été créé pour un domaine différent. Les passkeys sont liés au domaine — un passkey pour localhost:4321 ne fonctionnera pas sur example.com. Enregistrez un nouveau passkey pour chaque domaine.

”Session expirée”

Les sessions durent 30 jours par défaut avec expiration glissante. Si vous êtes déconnecté de manière inattendue, effacez vos cookies et reconnectez-vous.

Perdu tous les passkeys

Si vous avez perdu l’accès à tous vos passkeys enregistrés :

  1. Demandez à un autre administrateur de vous envoyer un lien magique (nécessite une configuration e-mail)
  2. Utilisez le lien magique pour vous connecter
  3. Enregistrez un nouveau passkey dans les paramètres du compte

Si vous êtes le seul administrateur et que l’e-mail n’est pas configuré, vous devrez réinitialiser l’authentification de votre site via la base de données.

Cloudflare Access

Lors du déploiement sur Cloudflare, vous pouvez utiliser Cloudflare Access comme fournisseur d’authentification au lieu des passkeys. Access gère l’authentification en périphérie en utilisant votre fournisseur d’identité existant.

Pourquoi utiliser Cloudflare Access

  • Single Sign-On — Les utilisateurs s’authentifient avec l’IdP de votre entreprise
  • Contrôle d’accès centralisé — Gérez qui peut accéder à l’administration dans le tableau de bord Cloudflare
  • Pas de gestion de passkey — Pas besoin d’enregistrer ou de gérer des passkeys
  • Rôles basés sur les groupes — Correspondre automatiquement les groupes IdP aux rôles EmDash

Configuration

  1. Créez une application Cloudflare Access pour votre site EmDash
  2. Notez le Application Audience (AUD) Tag des paramètres de l’application
  3. Configurez EmDash pour utiliser Access :
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",
				audience: "abc123def456...", // From Access app settings
			}),
		}),
	],
});

Options de configuration

OptionTypePar défautDescription
teamDomainstringrequisVotre domaine d’équipe Access (par exemple, myteam.cloudflareaccess.com)
audiencestringrequisBalise Application Audience (AUD) des paramètres Access
autoProvisionbooleantrueCréer des utilisateurs EmDash lors de la première connexion Access
defaultRolenumber30Rôle pour les utilisateurs ne correspondant à aucun groupe (30 = Author)
syncRolesbooleanfalseMettre à jour le rôle à chaque connexion en fonction des groupes IdP
roleMappingobjectCorrespondre les noms de groupes IdP aux niveaux de rôles
audienceEnvVarstring"CF_ACCESS_AUDIENCE"Nom de variable d’environnement pour la balise d’audience (alternative au codage en dur)

Correspondance des rôles

Correspondez vos groupes IdP aux rôles EmDash :

emdash({
	auth: access({
		teamDomain: "myteam.cloudflareaccess.com",
		audience: "abc123...",
		roleMapping: {
			Admins: 50, // Admin
			"Content Editors": 40, // Editor
			Writers: 30, // Author
		},
		defaultRole: 20, // Contributor pour les utilisateurs ne faisant partie d'aucun groupe
	}),
});

Le premier groupe correspondant l’emporte si un utilisateur appartient à plusieurs groupes. Le premier utilisateur à accéder au site devient toujours Admin, indépendamment des groupes.

Comportement de synchronisation des rôles

Par défaut (syncRoles: false), le rôle d’un utilisateur est défini lors de sa première connexion et ne change pas par la suite. Cela permet aux administrateurs d’ajuster manuellement les rôles dans EmDash.

Définissez syncRoles: true si vous voulez que les groupes IdP soient autoritaires — le rôle de l’utilisateur sera mis à jour à chaque connexion en fonction de ses groupes actuels.

Comment ça marche

  1. L’utilisateur visite /_emdash/admin
  2. Cloudflare Access intercepte et redirige vers votre IdP
  3. L’utilisateur s’authentifie (SSO, MFA, etc.)
  4. Access définit un JWT signé dans la demande
  5. EmDash valide le JWT et crée/authentifie l’utilisateur

Fonctionnalités désactivées

Lorsque Access est activé, ces fonctionnalités ne sont pas disponibles :

  • Page de connexion (/_emdash/admin/login)
  • Enregistrement et gestion des passkeys
  • Connexion OAuth
  • Connexion par lien magique
  • Auto-inscription
  • Invitations d’utilisateurs

La gestion des utilisateurs se fait entièrement via vos politiques Cloudflare Access.

Dépannage

”Aucun JWT Access présent”

La demande a atteint EmDash sans JWT Access. Cela signifie :

  • Access n’est pas configuré pour protéger votre application
  • La politique Access ne correspond pas aux routes d’administration

Vérifiez que votre application Access couvre /_emdash/admin/*.

”Inadéquation de l’audience JWT”

L’audience dans votre configuration ne correspond pas au JWT. Vérifiez le Application Audience Tag dans les paramètres de votre application Access.

”Utilisateur non autorisé”

L’utilisateur s’est authentifié via Access mais autoProvision est false et il n’existe pas dans EmDash. Soit :

  • Définissez autoProvision: true, soit
  • Créez l’utilisateur manuellement avant qu’il ne se connecte