Panoramica
L’autenticazione in Snapp è consapevole dell’host, scoped per organizzazione e applicata lato server.
È costruita su Better-Auth, estesa per supportare:
- deployment multi-host
- identità per organizzazione
- ruoli e permessi dinamici
- flussi basati su email
- provider OAuth opzionali
- API key
- autenticazione a due fattori (2FA) obbligatoria
Non esiste fiducia lato client. Tutte le decisioni di autenticazione e autorizzazione sono risolte sul server usando l’host e l’organizzazione attivi.
Confini dell’autenticazione
L’autenticazione è scoped su tre dimensioni:
Host Derivato dall’origine della richiesta e confrontato con
settings.yaml.Organizzazione Determinata dall’host e mappata a uno slug usato come identificatore canonico.
Sessione Basata su cookie, validata a ogni richiesta.
Una sessione non è mai valida al di fuori del proprio contesto di host e organizzazione.
Istanze di autenticazione per host
Snapp mantiene un’istanza di autenticazione dedicata per ogni host.
Ogni host crea il proprio client Better-Auth
Le istanze sono cachate in memoria
La cache viene invalidata quando:
- i ruoli vengono aggiornati
- i team vengono modificati
- le organizzazioni cambiano
- cambia la configurazione dell’host
Questo garantisce isolamento senza duplicare l’infrastruttura.
Metodi di autenticazione supportati
Username e password
- Metodo di autenticazione primario
- Le password sono hashate
- La verifica email è obbligatoria
- Il sign-in automatico è disabilitato
La registrazione può essere disabilitata per host:
disable:
signup: true
Verifica email
Richiesta prima dell’attivazione dell’account
Le email di verifica vengono inviate:
- alla registrazione
- al login se l’email non è ancora verificata
Se SMTP è disabilitato, le email di verifica vengono loggate su stdout.
Recupero password
- Flusso di reset basato su token
- I token sono monouso
- I link di reset sono vincolati all’host di origine
- La consegna segue la configurazione SMTP
Autenticazione a due fattori (2FA)
Snapp applica 2FA basato su TOTP per default.
Modello di enforcement
- Gli utenti senza 2FA vengono reindirizzati alla configurazione
- L’accesso alle route protette è bloccato finché il setup non è completato
- L’enforcement può essere disabilitato per host:
disable:
twoFactor: true
Flusso di configurazione 2FA
Durante il setup, all’utente vengono forniti:
- Un URI TOTP
- Un QR code generato lato server
- Un set di codici di backup monouso
Il modal di configurazione consente di:
- Scansionare il QR code con un’app di autenticazione
- Scaricare il QR code come SVG
- Scaricare l’URI TOTP grezzo come file di testo
- Scaricare i codici di backup come file di testo
Tutti gli artefatti sono generati lato client a partire da dati emessi dal server. Il segreto non viene mai memorizzato o ritrasmesso dopo il setup.
Codici di backup
- Generati una sola volta durante il setup
- Mostrati una sola volta
- Devono essere scaricati esplicitamente dall’utente
- Utilizzabili se il dispositivo di autenticazione viene perso
Snapp non rigenera automaticamente i codici di backup.
Verifica OTP
Dopo il setup:
- Gli utenti devono confermare un OTP valido
- La validazione OTP è applicata lato server
- I tentativi falliti vengono rifiutati senza rivelare stato
API key
Le API key sono credenziali di autenticazione di primo livello.
- Generate per utente
- Scadenza opzionale
- Soggette a rate limiting
- Scoped per organizzazione
I limiti derivano dai limiti dell’host:
requestsPerDayrequestsPerMinute
Le API key sono soggette alle stesse regole di enforcement delle sessioni autenticate, a meno che i limiti non siano disabilitati.
Autenticazione OAuth
Snapp supporta provider OAuth opzionali.
Provider supportati
- GitHub
OAuth è abilitato solo se le credenziali del provider sono presenti nell’ambiente.
La configurazione dei provider viene caricata da:
config/oauth.json
Comportamento OAuth
- Gli account OAuth vengono collegati agli utenti
- Se esiste un account corrispondente, viene riutilizzato
- Altrimenti viene creato un nuovo utente
- Le regole di verifica email restano applicate
OAuth non bypassa:
- appartenenza all’organizzazione
- controlli dei permessi
- enforcement del 2FA
- validazione della watchlist
Organizzazioni
Le organizzazioni sono entità di autenticazione di primo livello.
Proprietà chiave:
- Gli utenti possono appartenere a più organizzazioni
- Un’organizzazione è sempre attiva
- L’ID organizzazione è derivato dall’origine dell’host
- L’accesso cross-organizzazione è vietato
A ogni richiesta:
- L’organizzazione attiva viene validata
- Se mancante, viene impostata automaticamente
- Se non valida, l’accesso viene negato o reindirizzato
Team
I team esistono all’interno delle organizzazioni e sono usati per permessi scoped.
Consentono:
- controllo degli accessi granulare
- proprietà condivisa delle risorse
- delega dei permessi senza inflazione dei ruoli
Ruoli e permessi
Snapp utilizza un modello di controllo degli accessi esplicito.
Ruoli
I ruoli di default includono:
owneradminmember
I ruoli definiscono i permessi in modo dichiarativo, non tramite logica implicita.
Permessi
I permessi sono espressi come azioni su risorse:
create
read
update
delete
cancel
Esempio:
urls: ['create', 'read', 'update', 'delete']
I permessi sono:
- valutati lato server
- scoped per organizzazione e team
- ricaricabili dinamicamente
Modello di permessi dinamico
I permessi sono memorizzati nel database e uniti ai default a runtime.
Effetti:
- Nessun redeploy richiesto
- Le modifiche si propagano immediatamente
- Le cache di autenticazione vengono invalidate automaticamente
Enforcement dell’autorizzazione
Ogni operazione protetta esegue controlli espliciti sui permessi.
Esempi:
- Creazione URL →
urls.create - Aggiornamento URL →
urls.update - Eliminazione URL →
urls.delete - Creazione team →
team.create - Aggiornamento ruoli →
team.update
Lo stato della UI non implica mai autorizzazione.
Inviti
Snapp supporta onboarding controllato tramite inviti.
Inviti alle organizzazioni
- Invita utenti in un’organizzazione
- Assegna ruoli
- Scadenza opzionale
- Flusso di accettazione vincolato all’host
Inviti utenti admin
- Creazione utenti senza registrazione pubblica
- Forzatura del setup password via email
- Usato in ambienti ristretti
Gestione delle sessioni
- Sessioni basate su cookie
- Cache di sessione a breve durata (5 minuti)
- Refresh automatico
- Le sessioni non valide vengono rifiutate
Gli utenti vengono reindirizzati in base allo stato:
- non autenticato → sign-in
- organizzazione mancante → flusso di invito
- 2FA mancante → flusso di setup
Enforcement della watchlist
L’autenticazione è soggetta alle regole di watchlist.
I controlli includono:
- username
- dominio
Un controllo fallito comporta il rifiuto dell’autenticazione senza mutazione di stato.
Modello di consegna delle email
Le email legate all’autenticazione sono:
- renderizzate lato server
- inviate via SMTP se abilitato
- loggate su stdout se SMTP è disabilitato
Email supportate:
- verifica
- reset password
- OTP
- invito organizzazione
- invito admin
Garanzie
- L’autenticazione è isolata per host
- L’autorizzazione è applicata lato server
- I segreti non vengono mai esposti due volte
- Il 2FA non può essere bypassato lato client
- Le modifiche di configurazione si applicano live
Note
- Il comportamento dell’autenticazione è guidato da
settings.yaml - OAuth è opzionale
- SMTP è opzionale
- Le release beta possono estendere provider e primitive di permesso