Il pacchetto @emdash-cms/auth-atproto aggiunge un’opzione di accesso con account Atmosphere a EmDash. Un account Atmosphere è un’identità portabile di proprietà dell’utente utilizzata su Bluesky e altre app nella rete del protocollo AT. Gli utenti accedono con il loro handle (es. alice.bsky.social) e si autenticano presso il proprio provider — EmDash non vede mai una password.
Questa è una buona soluzione quando:
- I tuoi collaboratori hanno già un account Atmosphere.
- Vuoi controllare l’accesso a un dominio controllato dall’organizzazione (
*.tuaazienda.com) senza gestire app OAuth o inviti. - Stai costruendo qualcosa che fa parte dell’Atmosphere più ampio e vuoi un’identità coerente con il resto del tuo stack.
Installazione
Installa il pacchetto del provider:
pnpm add @emdash-cms/auth-atproto
Aggiungi il provider all’integrazione EmDash:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { atproto } from "@emdash-cms/auth-atproto";
export default defineConfig({
integrations: [
emdash({
authProviders: [atproto()],
server: {
host: "127.0.0.1", // required for local dev — see "Local development" below
},
}),
],
});
Questo è sufficiente per mostrare Accedi con Atmosphere sulla pagina di accesso e nella procedura guidata di configurazione. Senza una lista di autorizzazioni configurata, il primo utente diventa Admin e l’auto-registrazione viene chiusa per tutti gli altri — vedi liste di autorizzazioni per aprirla.
Il provider è un client OAuth pubblico e serve il proprio documento di metadati su /.well-known/atproto-client-metadata.json, quindi funziona solo con la configurazione sopra — nessuna variabile di ambiente, segreto client o registrazione di app OAuth da configurare.
Configurazione
Il provider atproto() accetta una lista di autorizzazioni e un ruolo predefinito:
atproto({
allowedDIDs: ["did:plc:abc123..."],
allowedHandles: ["*.example.com", "alice.bsky.social"],
defaultRole: 30, // Author
});
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
allowedDIDs | string[] | nessuno (consenti tutti al primo) | Lista di autorizzazioni DID. I DID sono permanenti e non possono essere falsificati. |
allowedHandles | string[] | nessuno (consenti tutti al primo) | Lista di autorizzazioni handle. Supporta wildcard (*.example.com). |
defaultRole | number | 10 (Subscriber) | Ruolo assegnato agli utenti autorizzati dopo il primo. Il primo utente è sempre Admin. |
La scala completa dei ruoli è documentata nella guida all’autenticazione principale.
Liste di autorizzazioni
Se né allowedDIDs né allowedHandles sono impostati, solo il primo utente può registrarsi — chiunque altro tenti di accedere verrà rifiutato con signup_not_allowed. Gli utenti esistenti possono sempre accedere nuovamente indipendentemente dalla lista di autorizzazioni (quindi rimuoverti dalla lista non ti bloccherà, ma non lascerà entrare nemmeno nuove persone).
Quando almeno una lista di autorizzazioni è configurata, un utente viene ammesso se una delle due liste corrisponde:
- Corrispondenza DID. Il DID dell’utente è in
allowedDIDs. I DID sono identificatori crittografici che non possono essere spostati o impersonati, quindi questa è la forma più rigorosa di controllo degli accessi. - Corrispondenza handle. L’handle dell’utente corrisponde a una voce in
allowedHandles, esattamente o tramite un pattern wildcard iniziale (*.example.comcorrisponde aalice.example.comebob.team.example.com).
Le liste di autorizzazioni handle sono sicure anche se gli handle sono mutabili. Prima di ammettere un utente tramite una corrispondenza handle, EmDash risolve indipendentemente il record DNS/HTTP dell’handle e verifica che punti allo stesso DID che il provider afferma. Un provider malevolo non può semplicemente affermare di possedere tu@tuaazienda.com.
Ruolo predefinito
Gli utenti autorizzati finiscono sul ruolo che imposti in defaultRole. Solo il primo utente — quello che completa la configurazione — è forzato ad Admin. Non esiste mapping gruppo/ruolo per gli account Atmosphere; se hai bisogno di ruoli più granulari, modifica il ruolo dell’utente da Impostazioni → Utenti dopo che si sono connessi una volta.
Configurazione del primo utente
Quando avvii un nuovo sito con il provider Atmosphere configurato, la procedura guidata di configurazione lo offre come opzione per creare l’account amministratore iniziale.
-
Visita
/_emdash/admin. La procedura guidata di configurazione ti guida attraverso titolo del sito, slogan e email dell’amministratore. -
Nel passaggio “Crea account amministratore”, scegli Atmosphere e inserisci il tuo handle (es.
alice.bsky.social). -
Verrai reindirizzato alla pagina di autorizzazione del tuo account, dove accedi come supportato dal tuo provider — password, passkey o altro.
-
Dopo l’approvazione vieni rimandato a EmDash, l’utente amministratore viene creato con ruolo 50 (Admin), e l’email che hai inserito nel passaggio 1 viene memorizzata contro il tuo account.
Lo stesso flusso viene eseguito per ogni accesso successivo: inserisci il tuo handle, autenticati presso il tuo provider e torna a EmDash connesso.
Sviluppo locale
Il profilo OAuth del protocollo AT richiede che gli URI di reindirizzamento loopback utilizzino un literal IP (127.0.0.1 o [::1]), non localhost. EmDash riscrive in modo trasparente ://localhost in ://127.0.0.1 quando genera l’URI di reindirizzamento, ma ciò significa che anche la tua sessione di sviluppo deve iniziare su 127.0.0.1 — altrimenti il cookie di sessione impostato su localhost non sarà visibile dopo che il reindirizzamento ti porta su 127.0.0.1.
Il server di sviluppo di Astro è il server di sviluppo di Vite, e Vite si lega a localhost per impostazione predefinita. Digli di ascoltare anche sull’IP di loopback:
export default defineConfig({
server: {
host: "127.0.0.1",
},
// ...
});
Quindi apri http://127.0.0.1:4321/_emdash/admin per l’intero flusso.
Produzione
La stessa configurazione funziona in produzione. Il provider serve i propri metadati client su:
https://your-site.example.com/.well-known/atproto-client-metadata.json
I server di autorizzazione recuperano questo URL durante l’accesso per verificare l’URI di reindirizzamento del client. Assicurati che l’URL del sito della tua distribuzione sia raggiungibile su internet pubblico tramite HTTPS — le distribuzioni solo interne dietro una VPN non potranno completare un accesso perché il server di autorizzazione dell’utente non può recuperare il documento di metadati.
Se esegui EmDash dietro un proxy inverso che termina TLS, imposta siteUrl in modo che EmDash costruisca l’URI di reindirizzamento corretto. Senza di esso, le richieste appaiono come http://internal-host:4321 e i metadati non corrisponderanno a ciò che vede il server di autenticazione.
Risoluzione dei problemi
”Account is not in the allowlist”
L’handle o il DID con cui hai effettuato l’accesso non è in allowedDIDs / allowedHandles. Controlla il pattern wildcard (deve iniziare con *.) e ricorda che la corrispondenza handle viene verificata contro DNS/HTTP — se il record DID dell’handle attualmente non si risolve nello stesso DID restituito dal provider, la corrispondenza viene rifiutata.
”Self-signup is not allowed”
Hai raggiunto il callback con successo ma nessuna lista di autorizzazioni è configurata e non sei il primo utente. O aggiungiti a allowedDIDs/allowedHandles, o fatti invitare da un amministratore esistente in modo che l’utente esista già quando accedi.
L’accesso reindirizza alla pagina di accesso senza errore
Questo è quasi sempre il problema del cookie loopback descritto in Sviluppo locale. Apri l’admin su http://127.0.0.1:4321 (dopo aver impostato server.host: "127.0.0.1") e riprova.
La risoluzione handle fallisce per un handle auto-ospitato
Il provider verifica gli handle facendo una gara tra DNS-over-HTTPS (endpoint DoH di Cloudflare) e una ricerca HTTP /.well-known/atproto-did. Gli handle auto-ospitati necessitano di almeno uno di:
- Un record DNS TXT
_atproto.<handle>contenentedid=<tuo-did>, o - Un file
https://<handle>/.well-known/atproto-didcontenente il DID.
Se entrambi i metodi falliscono, la corrispondenza handle viene rifiutata anche quando l’account sottostante è valido. I DID in allowedDIDs non sono interessati — vengono confrontati direttamente.