Secrets et gestion des clés

Sur cette page

EmDash utilise un petit ensemble de secrets pour les aperçus, les commentaires, l’authentification, le stockage et les plugins. Cette page est l’inventaire complet : d’où vient chaque secret, où il est stocké, comment le faire tourner et ce qui casse s’il est perdu.

Vue d’ensemble

SecretSourceStocké dansImpact en cas de perte
EMDASH_ENCRYPTION_KEYOpérateur (emdash secrets generate)Environnement / secret Worker uniquementLes secrets de plugins chiffrés deviennent irrécupérables (quand le chiffrement au repos sera déployé)
Secret d’aperçuAuto-généré (override env)Table options (emdash:preview_secret)Les liens d’aperçu en cours cessent de fonctionner ; les nouveaux sont OK
Sel IPAuto-généré (override env)Table options (emdash:ip_salt)La continuité du rate-limit des commentaires se réinitialise
Tokens de session et APIGénérés par session/tokenStore de sessions / BD (hashes uniquement)Rien — le texte en clair n’est jamais stocké
Identifiants OAuthVous (console Google/GitHub)EnvironnementLa connexion via ce fournisseur s’arrête jusqu’au remplacement
Secret TurnstileVous (tableau de bord Cloudflare)EnvironnementLa vérification CAPTCHA des commentaires échoue
Identifiants S3Vous (fournisseur de stockage)Environnement ou configurationL’upload/download de médias échoue jusqu’au remplacement
Secrets de pluginsVous (UI d’administration)Base de données (paramètres / stockage plugins)Ressaisir dans l’admin
Identifiants CLIFlux de dispositif emdash login / emdash plugin publish~/.config/emdash/auth.json (mode 0600)Relancer le flux de dispositif
Identifiants CLI du registreemdash-plugin atproto OAuth~/.emdash/oauth/, ~/.emdash/credentials.json (mode 0600)Se reconnecter ; l’identité réside dans votre PDS

La clé de chiffrement

EMDASH_ENCRYPTION_KEY est la clé du site pour chiffrer les secrets de plugins au repos. Elle est fournie par l’opérateur et jamais stockée dans la base de données — la base de données ne contient que du texte chiffré, une fuite de sauvegarde n’expose donc pas la clé.

Générez-en une et définissez-la comme variable d’environnement (ou secret Worker) :

npx emdash secrets generate
# emdash_enc_v1_<43 caractères base64url>

# Cloudflare :
wrangler secret put EMDASH_ENCRYPTION_KEY

Le format est emdash_enc_v1_ suivi de 32 octets aléatoires en base64url non paddé. La clé est validée au démarrage du runtime ; une valeur malformée enregistre une erreur côté opérateur sans interrompre les chemins de requête.

Rotation

La variable accepte une liste de clés séparées par des virgules. La première entrée est la primaire et est utilisée pour les nouvelles écritures ; toutes les entrées sont essayées pour le déchiffrement. Chaque valeur chiffrée est étiquetée avec une empreinte de clé de 8 caractères (le kid, affichable via emdash secrets fingerprint <key>), le runtime choisit donc automatiquement la bonne clé.

Pour faire tourner : générez une nouvelle clé, préfixez-la à la liste (EMDASH_ENCRYPTION_KEY="nouvelle,ancienne"), redéployez et supprimez l’ancienne une fois les valeurs existantes re-chiffrées.

Secrets de site générés

Deux secrets sont générés automatiquement lors de la première utilisation et persistés dans la table options, ils sont donc stables entre les requêtes, déploiements et isolats. La génération est atomique — les démarrages à froid concurrents convergent vers une seule valeur.

Secret d’aperçu

Signe les URLs d’aperçu (HMAC). Stocké comme emdash:preview_secret ; 32 octets aléatoires, base64url.

  • Override : définissez EMDASH_PREVIEW_SECRET (alias hérité : PREVIEW_SECRET) si vous avez besoin du même secret sur plusieurs processus ou souhaitez le fixer pour des raisons d’audit. L’environnement l’emporte toujours sur la valeur stockée.
  • Rotation : supprimez la ligne emdash:preview_secret (ou changez la variable d’env) et redéployez. Impact : les liens d’aperçu émis précédemment cessent de valider. Rien d’autre ne casse — un nouveau secret est généré (ou lu depuis l’env) à la prochaine requête d’aperçu.
  • En cas de perte : rien n’est irrécupérable. Les liens d’aperçu sont éphémères par conception.

Consultez le guide d’aperçu pour la construction et la vérification des URLs d’aperçu.

Sel IP

Sale le hash SHA-256 des adresses IP des commentateurs (ip_hash sur les commentaires) utilisé pour la limitation de débit des commentaires. Stocké comme emdash:ip_salt. Spécifique au site, les hashes ne sont donc pas corrélables entre les installations EmDash.

  • Override : définissez EMDASH_IP_SALT. Pour la rétrocompatibilité, EMDASH_AUTH_SECRET / AUTH_SECRET sont aussi consultés — les installations qui dérivaient historiquement le sel de ceux-ci conservent des hashes stables.
  • Rotation : changez la variable d’env ou supprimez la ligne emdash:ip_salt. Impact : les nouveaux commentaires produisent des valeurs de hash différentes, le comptage de rate-limit redémarre pour tous. Les commentaires existants et leurs hashes stockés ne sont pas touchés.
  • En cas de perte : aucune perte de données. Seule la continuité du rate-limit se réinitialise.

Tokens de session et API

  • Sessions utilisent le store de sessions d’Astro (Workers KV sur Cloudflare, système de fichiers sur Node). Le cookie porte un ID de session opaque ; il n’y a pas de secret de signature à gérer. Déconnectez-vous pour terminer une session, ou videz le store de sessions (ex. le namespace KV) pour forcer tout le monde à se reconnecter.
  • Tokens API (préfixes ec_pat_, ec_oat_, ec_ort_) sont des valeurs aléatoires opaques de 256 bits ; seul leur hash SHA-256 est stocké. Le texte en clair est montré une seule fois à la création. Faites tourner en révoquant et recréant dans l’admin.
  • Tokens d’invitation, magic-link et récupération sont à usage unique, stockés comme hashes SHA-256 dans auth_tokens, et limités dans le temps (invitations 7 jours, magic links 15 minutes).

Il n’y a rien à sauvegarder ou faire tourner de manière proactive : une fuite de base de données n’expose que des hashes, et chaque token peut être révoqué ou réémis depuis l’admin.

Identifiants de service fournis par l’utilisateur

Les identifiants pour les services externes sont lus depuis l’environnement et jamais écrits dans la base de données. Faites-les tourner chez le fournisseur, mettez à jour la variable, redéployez.

ServiceVariables
Connexion GoogleEMDASH_OAUTH_GOOGLE_CLIENT_ID, EMDASH_OAUTH_GOOGLE_CLIENT_SECRET (ou alias non préfixés)
Connexion GitHubEMDASH_OAUTH_GITHUB_CLIENT_ID, EMDASH_OAUTH_GITHUB_CLIENT_SECRET (ou alias non préfixés)
Publication Marketplace (CI)EMDASH_MARKETPLACE_TOKEN
Turnstile (commentaires)EMDASH_TURNSTILE_SECRET_KEY (ou TURNSTILE_SECRET_KEY)
Stockage compatible S3S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_BUCKET, S3_REGION

Sur Cloudflare, définissez-les avec wrangler secret put ; localement, mettez-les dans .env. R2 via binding ne nécessite aucun identifiant — l’accès est accordé par le binding dans wrangler.jsonc, qui est la configuration recommandée sur Workers. Voir options de stockage.

Secrets de plugins

Les paramètres qu’un plugin déclare avec type: "secret" (clés API pour les fournisseurs d’email, CAPTCHAs de formulaires, etc.) sont saisis dans l’UI d’admin et stockés dans la base de données — dans la table options sous plugin:<id>:settings:<key>, ou dans le stockage clé-valeur du plugin. Si un secret stocké est renvoyé à l’UI d’admin dépend du plugin ; les plugins bien écrits renvoient seulement un indicateur « valeur définie » au lieu du secret lui-même (le plugin de formulaires intégré fait cela).

  • Rotation : faites tourner la clé chez le fournisseur et collez la nouvelle valeur dans la page de paramètres du plugin. Prend effet immédiatement.
  • En cas de perte : ressaisissez la valeur dans l’admin. Rien d’autre n’en dépend.

Identifiants CLI

La CLI emdash détient deux types d’identifiants, tous deux dans ~/.config/emdash/auth.json (respectant XDG_CONFIG_HOME), créés avec des permissions propriétaire uniquement (0600) :

  • Tokens de siteemdash login s’authentifie contre votre instance EmDash via un flux de dispositif OAuth et stocke le token résultant indexé par URL d’instance. emdash logout le supprime ; par invocation, --token ou EMDASH_TOKEN remplace le token stocké.
  • Tokens Marketplaceemdash plugin publish s’authentifie auprès du EmDash Marketplace via un flux de dispositif GitHub et stocke le JWT résultant indexé comme marketplace:<origin>. Pour la publication CI, définissez EMDASH_MARKETPLACE_TOKEN à la place — il a priorité sur l’identifiant stocké.

Perdre le fichier est sans conséquence : relancez emdash login (ou emdash plugin publish, qui relance le flux de dispositif).

Identifiants CLI du registre de plugins

La CLI séparée emdash-plugin (paquet @emdash-cms/plugin-cli) cible le registre expérimental AT Protocol. La publication y est liée à votre identité AT Protocol (votre DID d’éditeur) — le site lui-même ne détient pas d’identifiants de publication, et les installations vérifient les artefacts contre les checksums des enregistrements de release attribués à ce DID.

  • Elle s’authentifie via atproto OAuth. Les blobs de session/état OAuth résident dans ~/.emdash/oauth/, et l’identité d’éditeur (DID, handle, PDS) est mise en cache dans ~/.emdash/credentials.json ; les deux sont écrits avec des permissions propriétaire uniquement.
  • En CI, fournissez l’identité via EMDASH_PUBLISHER_DID, EMDASH_PUBLISHER_HANDLE et EMDASH_PUBLISHER_PDS ; EMDASH_REGISTRY_URL remplace l’hôte du registre. Le publish automatisé depuis CI nécessite toujours les fichiers de session OAuth dans ~/.emdash/oauth/ sur le runner — les variables d’env seules ne portent pas la session OAuth.
  • La rotation ou la révocation de l’accès de publication se fait sur votre compte AT Protocol (ex. mots de passe d’application), pas dans EmDash. Voir Atmosphere auth.

Référence rapide de rotation

Je veux…Faire ceci
Faire tourner la clé de chiffrementPréfixer une nouvelle clé : EMDASH_ENCRYPTION_KEY="nouvelle,ancienne", redéployer, supprimer l’ancienne plus tard
Invalider tous les liens d’aperçuSupprimer la ligne d’option emdash:preview_secret (ou changer l’override env)
Réinitialiser le hashing de rate-limitChanger EMDASH_IP_SALT (ou supprimer la ligne d’option emdash:ip_salt)
Révoquer un token API divulguéAdmin → Utilisateurs → Tokens API → révoquer, puis créer un remplacement
Terminer toutes les sessionsVider le store de sessions (namespace Workers KV / répertoire de sessions)
Remplacer un identifiant de fournisseurFaire tourner chez le fournisseur, mettre à jour la variable d’env, redéployer
Remplacer une clé API de pluginFaire tourner chez le fournisseur, ressaisir dans les paramètres admin du plugin