Segreti e gestione delle chiavi

In questa pagina

EmDash utilizza un piccolo insieme di segreti per anteprime, commenti, autenticazione, archiviazione e plugin. Questa pagina è l’inventario completo: da dove proviene ogni segreto, dove viene archiviato, come ruotarlo e cosa si rompe se viene perso.

Panoramica

SegretoFonteArchiviato inImpatto in caso di perdita
EMDASH_ENCRYPTION_KEYOperatore (emdash secrets generate)Solo ambiente / segreto WorkerI segreti dei plugin crittografati diventano irrecuperabili (quando la crittografia a riposo sarà attiva)
Segreto di anteprimaAuto-generato (override env)Tabella options (emdash:preview_secret)I link di anteprima esistenti smettono di funzionare; i nuovi sono OK
Salt IPAuto-generato (override env)Tabella options (emdash:ip_salt)La continuità del rate-limit dei commenti si resetta
Token di sessione e APIGenerati per sessione/tokenStore sessioni / DB (solo hash)Niente — il testo in chiaro non viene mai archiviato
Credenziali provider OAuthTu (console Google/GitHub)AmbienteL’accesso tramite quel provider si ferma fino alla sostituzione
Segreto TurnstileTu (dashboard Cloudflare)AmbienteLa verifica CAPTCHA dei commenti fallisce
Credenziali S3Tu (provider di archiviazione)Ambiente o configurazioneUpload/download dei media fallisce fino alla sostituzione
Segreti dei pluginTu (UI impostazioni admin)Database (impostazioni / archiviazione plugin)Reinserire nell’admin
Credenziali CLIFlussi dispositivo emdash login / emdash plugin publish~/.config/emdash/auth.json (modo 0600)Rieseguire il flusso dispositivo
Credenziali CLI del registroemdash-plugin atproto OAuth~/.emdash/oauth/, ~/.emdash/credentials.json (modo 0600)Effettuare nuovamente l’accesso; l’identità risiede nel tuo PDS

La chiave di crittografia

EMDASH_ENCRYPTION_KEY è la chiave del sito per crittografare i segreti dei plugin a riposo. È fornita dall’operatore e mai archiviata nel database — il database contiene solo testo cifrato, quindi un backup trapelato non espone la chiave.

Generane una e impostala come variabile d’ambiente (o segreto Worker):

npx emdash secrets generate
# emdash_enc_v1_<43 caratteri base64url>

# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY

Il formato è emdash_enc_v1_ seguito da 32 byte casuali come base64url senza padding. La chiave viene validata all’avvio del runtime; un valore malformato registra un errore lato operatore senza interrompere i percorsi di richiesta.

Rotazione

La variabile accetta una lista di chiavi separate da virgola. La prima voce è la primaria e viene usata per le nuove scritture; tutte le voci vengono provate per la decrittografia. Ogni valore crittografato è etichettato con un’impronta della chiave di 8 caratteri (il kid, stampabile tramite emdash secrets fingerprint <key>), quindi il runtime seleziona automaticamente la chiave giusta.

Per ruotare: genera una nuova chiave, anteponila alla lista (EMDASH_ENCRYPTION_KEY="nuova,vecchia"), ridistribuisci e rimuovi la vecchia una volta che i valori esistenti sono stati ri-crittografati.

Segreti del sito generati

Due segreti vengono generati automaticamente al primo utilizzo e persistiti nella tabella options, quindi sono stabili tra richieste, deployment e isolati. La generazione è atomica — avvii a freddo concorrenti convergono su un unico valore.

Segreto di anteprima

Firma gli URL di anteprima (HMAC). Archiviato come emdash:preview_secret; 32 byte casuali, base64url.

  • Override: imposta EMDASH_PREVIEW_SECRET (alias legacy: PREVIEW_SECRET) se hai bisogno dello stesso segreto su più processi o vuoi fissarlo per motivi di audit. L’ambiente prevale sempre sul valore archiviato.
  • Rotazione: elimina la riga emdash:preview_secret (o cambia la variabile d’env) e ridistribuisci. Impatto: i link di anteprima emessi in precedenza smettono di validare. Nient’altro si rompe — un segreto fresco viene generato (o letto dall’env) alla prossima richiesta di anteprima.
  • In caso di perdita: niente è irrecuperabile. I link di anteprima sono effimeri per design.

Consulta la guida alle anteprime per come vengono costruiti e verificati gli URL di anteprima.

Salt IP

Sala l’hash SHA-256 degli indirizzi IP dei commentatori (ip_hash sui commenti) usato per il rate-limiting dei commenti. Archiviato come emdash:ip_salt. Specifico del sito, quindi gli hash non sono correlabili tra installazioni EmDash.

  • Override: imposta EMDASH_IP_SALT. Per retrocompatibilità, vengono consultati anche EMDASH_AUTH_SECRET / AUTH_SECRET — le installazioni che storicamente derivavano il salt da questi mantengono hash stabili.
  • Rotazione: cambia la variabile d’env o elimina la riga emdash:ip_salt. Impatto: i nuovi invii di commenti producono valori hash diversi, quindi il conteggio del rate-limit riparte per tutti. I commenti esistenti e i loro hash archiviati non vengono toccati.
  • In caso di perdita: nessuna perdita di dati. Solo la continuità del rate-limit si resetta.

Token di sessione e API

  • Sessioni usano lo store di sessioni di Astro (Workers KV su Cloudflare, filesystem su Node). Il cookie trasporta un ID di sessione opaco; non c’è segreto di firma da gestire. Disconnettiti per terminare una sessione, o svuota lo store di sessioni (es. il namespace KV) per forzare tutti a riconnettersi.
  • Token API (prefissi ec_pat_, ec_oat_, ec_ort_) sono valori casuali opachi a 256 bit; viene archiviato solo il loro hash SHA-256. Il testo in chiaro viene mostrato una sola volta alla creazione. Ruota revocando e ricreando nell’admin.
  • Token di invito, magic-link e recupero sono a scopo singolo, archiviati come hash SHA-256 in auth_tokens, e a tempo limitato (inviti 7 giorni, magic link 15 minuti).

Non c’è niente da sottoporre a backup o ruotare proattivamente: un leak del database espone solo hash, e ogni token può essere revocato o riemesso dall’admin.

Credenziali di servizio fornite dall’utente

Le credenziali per servizi esterni vengono lette dall’ambiente e mai scritte nel database. Ruotale presso il provider, aggiorna la variabile, ridistribuisci.

ServizioVariabili
Accesso GoogleEMDASH_OAUTH_GOOGLE_CLIENT_ID, EMDASH_OAUTH_GOOGLE_CLIENT_SECRET (o alias senza prefisso)
Accesso GitHubEMDASH_OAUTH_GITHUB_CLIENT_ID, EMDASH_OAUTH_GITHUB_CLIENT_SECRET (o alias senza prefisso)
Pubblicazione Marketplace (CI)EMDASH_MARKETPLACE_TOKEN
Turnstile (commenti)EMDASH_TURNSTILE_SECRET_KEY (o TURNSTILE_SECRET_KEY)
Storage compatibile S3S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_BUCKET, S3_REGION

Su Cloudflare, impostale con wrangler secret put; localmente, mettile in .env. R2 tramite binding non necessita credenziali — l’accesso è concesso dal binding in wrangler.jsonc, che è il setup consigliato su Workers. Vedi opzioni di archiviazione.

Segreti dei plugin

Le impostazioni che un plugin dichiara con type: "secret" (chiavi API per provider email, CAPTCHA di moduli, ecc.) vengono inserite nell’UI admin e archiviate nel database — nella tabella options sotto plugin:<id>:settings:<key>, o nello storage chiave-valore del plugin. Se un segreto archiviato viene restituito all’UI admin dipende dal plugin; i plugin ben scritti restituiscono solo un flag “valore impostato” invece del segreto stesso (il plugin di moduli integrato fa questo).

  • Rotazione: ruota la chiave presso il provider e incolla il nuovo valore nella pagina delle impostazioni del plugin. Ha effetto immediato.
  • In caso di perdita: reinserisci il valore nell’admin. Nient’altro ne dipende.

Credenziali CLI

La CLI emdash detiene due tipi di credenziali, entrambi in ~/.config/emdash/auth.json (rispettando XDG_CONFIG_HOME), creati con permessi solo proprietario (0600):

  • Token del sitoemdash login si autentica contro la tua istanza EmDash tramite un flusso dispositivo OAuth e archivia il token risultante indicizzato per URL dell’istanza. emdash logout lo rimuove; per invocazione, --token o EMDASH_TOKEN sovrascrive il token archiviato.
  • Token Marketplaceemdash plugin publish si autentica presso il EmDash Marketplace tramite un flusso dispositivo GitHub e archivia il JWT risultante indicizzato come marketplace:<origin>. Per la pubblicazione CI, imposta EMDASH_MARKETPLACE_TOKEN invece — ha priorità sulla credenziale archiviata.

Perdere il file è innocuo: riesegui emdash login (o emdash plugin publish, che riesegue il flusso dispositivo).

Credenziali CLI del registro dei plugin

La CLI separata emdash-plugin (pacchetto @emdash-cms/plugin-cli) mira al registro sperimentale AT Protocol. La pubblicazione lì è legata alla tua identità AT Protocol (il tuo DID editore) — il sito stesso non detiene credenziali di pubblicazione, e le installazioni verificano gli artefatti contro i checksum dei record di release attribuiti a quel DID.

  • Si autentica tramite atproto OAuth. I blob di sessione/stato OAuth risiedono in ~/.emdash/oauth/, e l’identità editore (DID, handle, PDS) è memorizzata in cache in ~/.emdash/credentials.json; entrambi sono scritti con permessi solo proprietario.
  • In CI, fornisci l’identità tramite EMDASH_PUBLISHER_DID, EMDASH_PUBLISHER_HANDLE e EMDASH_PUBLISHER_PDS; EMDASH_REGISTRY_URL sovrascrive l’host del registro. Il publish automatizzato da CI necessita comunque dei file di sessione OAuth in ~/.emdash/oauth/ sul runner — le variabili d’env da sole non trasportano la sessione OAuth.
  • La rotazione o revoca dell’accesso di pubblicazione avviene nel tuo account AT Protocol (es. password per le app), non in EmDash. Vedi Atmosphere auth.

Riferimento rapido di rotazione

Voglio…Fare questo
Ruotare la chiave di crittografiaAnteporre nuova chiave: EMDASH_ENCRYPTION_KEY="nuova,vecchia", ridistribuire, rimuovere vecchia dopo
Invalidare tutti i link di anteprimaEliminare la riga opzione emdash:preview_secret (o cambiare l’override env)
Resettare l’hashing del rate-limitCambiare EMDASH_IP_SALT (o eliminare la riga opzione emdash:ip_salt)
Revocare un token API trapelatoAdmin → Utenti → Token API → revocare, poi creare sostituto
Terminare tutte le sessioniSvuotare lo store sessioni (namespace Workers KV / directory sessioni)
Sostituire una credenziale del providerRuotare presso il provider, aggiornare variabile d’env, ridistribuire
Sostituire una chiave API del pluginRuotare presso il provider, reinserire nelle impostazioni admin del plugin