[ AUTH & IDENTITÀ ]
Autenticazione che non devi costruire, su un database che è già tuo.
Sessioni, passkey, secondo fattore, SSO, organizzazioni e permessi per ruolo, in un solo modulo per Nuxt ed Elysia. La tabella utenti sta nel tuo PostgreSQL — noi non ne teniamo una copia.
Closed beta già in produzione con partner selezionatiCostruito su better-auth esteso, non forkatoIncluso nel piano Scale CHF 99 al mese
Lo usiamo prima di venderlo.
Ogni prodotto che facciamo girare fa entrare i suoi utenti da questo modulo — il nostro SaaS, le piattaforme dei clienti che gestiamo, il back office dietro questo sito. Non una prova di concetto: la cosa che ripariamo noi quando si rompe alle due di notte.
- Il tuo database, non il nostro
- Il modulo scrive sul tuo PostgreSQL. Nessun servizio JAMflow tiene una seconda copia dei tuoi utenti.
- Un modulo, non cinque integrazioni
- Sessioni, provider, organizzazioni, inviti e permessi arrivano insieme e si conoscono già fra loro.
- Chi l'ha scritto risponde al ticket
- Incontri un caso limite e parli con il team che ha scritto il modulo, non con un integratore che legge il README.
Cosa arriva, riga per riga.
Il modulo è better-auth già collegato, quindi quello che fa better-auth lo fa lui — con sopra il nostro livello di permessi e i pezzi operativi. Tutto quello che segue arriva già configurato, tranne dove la riga dice su richiesta.
Modi di entrare
- Email e password, con un reset che chiude tutte le sessioni aperte
- Magic link — uso singolo, a scadenza, salvato come hash
- Passkey via WebAuthn
- Secondo fattore con codice usa e getta
- Accesso social e aziendale via OIDC e OAuth2
Team, ruoli e registro
- Organizzazioni, membri e inviti che scadono
- Ruoli per organizzazione, dichiarati per risorsa e per azione
- Ruoli di piattaforma che si risolvono sopra ogni tenant
- Impersonation di supporto, dal livello di piattaforma
- Un registro append-only, incatenato per hash e verificabile
Isolamento e limiti
- Uno schema solo, scoping imposto dal framework
- Uno schema PostgreSQL per tenantsu richiesta
- Un database dedicatosu richiesta
- Rate limiting sulle rotte di auth, su Redis, condiviso fra le repliche
Autorizzazione
Ruoli che assomigliano al tuo prodotto, non all'idea che se ne fa una libreria.
I tuoi ruoli non dovrebbero vivere in un foglio di calcolo. Un prodotto vero ha titolari, responsabili della fatturazione, agenti di supporto e ospiti in sola lettura — e la stessa persona è titolare in un'organizzazione e spettatrice in quella dopo. Lo dichiari una volta; il controllo è una chiamata.
fino al 50%
di round-trip al database in meno, su una richiesta protetta
Un controllo dei permessi di solito costa una query: leggi la regola, poi fai il lavoro. Qui arriva dalla sessione che la richiesta porta già: due round-trip diventano uno. Aritmetica, non un benchmark — quanto risparmi dipende da cos'altro legge quella richiesta.
- I ruoli di piattaforma si risolvono prima
- Supporto e operations hanno un livello loro sopra i tenant, così nessuno viene fatto admin di un'organizzazione solo per rispondere a un ticket.
- Un vocabolario solo, server e interfaccia
- Lo stesso file lo importano il guard e l'interfaccia, così un bottone e la rotta che ci sta dietro non possono essere in disaccordo su chi può premerlo.
shared/permissions.ts
// One vocabulary, imported by the server and by the UIexport const org = createAccessControl({ ...defaultStatements, projects: ['read', 'update'], billing: ['read', 'update'], domains: ['read', 'create', 'update', 'delete'],}) export const member = org.newRole({ projects: ['read'], billing: ['read'],}) // A handler states both vocabularies; the platform one is tried firstawait requireResolvedPermission(event, { globalPermissions: { projects: ['update'] }, organizationPermissions: { projects: ['update'] },})Una persona, molte organizzazioni, niente travasi.
L'organizzazione attiva arriva dalla sessione, prima che parta la logica del tuo handler, e un membro che ne nomina un'altra nell'URL si vede rifiutare la richiesta, non servire un'altra in silenzio. Quel confine lo tiene il framework, nel codice applicativo — un confine vero, non invalicabile.
- Organizzazioni che le persone gestiscono da sole
- Creare, entrare, cambiare. Nessuno apre un ticket per spostare una persona da un team all'altro.
- Inviti che scadono
- Firmati, a scadenza, spediti via email, con il ruolo assegnato nel momento in cui l'invito viene accettato.
- Una sessione che sa già
- Chi è entrato, per quale organizzazione e cosa può fare — al primo render, senza stato di caricamento.
- Un livello di back office
- Gli operatori di piattaforma hanno gestione utenti e accesso su tutte le organizzazioni, separati dai ruoli interni di ogni tenant.
Un modulo, una migration, e lo schema è tuo.
Il modulo registra i suoi composable, le utility server, il middleware e le rotte, e porta il proprio set di migration Drizzle. Gli dai una stringa di connessione PostgreSQL, esegui la migration una volta, e le tabelle di identità sono nel tuo database, sotto le tue migration.
bun i @jamflow/authregistry privato — l'accesso arriva con il piano
Il resto degli strumenti è JAMlabs → Gira su JAMflow Postgres, Neon, o una tua istanza →
Dati e accesso
La tabella utenti è tua.
Lo schema sta sotto le migration Drizzle, nel tuo repository, e lo puoi leggere. Non c'è niente da cui esportare, perché niente di tuo sta da noi — e il registro di cosa hanno fatto le persone è append-only e incatenato per hash.
Lo giri a un ufficio sicurezza? Residenza dei dati, certificazioni e modello di deployment stanno sulla pagina enterprise, e quello che non è scritto lì lo rispondiamo di persona. Se il tuo ufficio acquisti ha bisogno oggi di un certificato intestato a noi, rileggi la prima riga di questa pagina. Come rispondiamo a una security review →
Domande prima di impegnarti.
Quelle che ci fanno davvero. Per tutto il resto chiedi direttamente — risponde una persona.
Chiedici qualcos'altro →È solo better-auth con una fattura attaccata?
No. better-auth è la base dell'autenticazione; tutto quello che ci sta sopra — il livello di permessi, il tier di piattaforma, un controllo che non costa una query, l'integrazione col runtime — è nostro. Se niente di questo vale il prezzo, usa better-auth direttamente: non ti chiederà soldi.
Quanto costa?
Arriva con il piano Scale a CHF 99 al mese, che porta anche CHF 150 di consumo incluso, gli altri moduli dello stesso livello e il supporto del piano. Nessuna licenza a parte per il modulo di auth, nessun prezzo per utente sopra.
Che database vuole?
PostgreSQL. JAMflow Postgres, Neon, o un'istanza che gestisci tu — lo schema in ogni caso è gestito dalle migration Drizzle, e resta nel tuo database invece che nel nostro.
Vedi JAMflow Postgres →Ho già better-auth. Ve lo potete prendere in carico?
Sì. O prendiamo in carico la manutenzione di quello che hai, o studiamo una migrazione sul modulo — compresi i casi che in un sistema di ruoli preconfezionato non entrano mai, che è buona parte del motivo per cui ci siamo scritti il nostro livello di permessi.
Funziona fuori da Nuxt?
Un modulo Nuxt e un plugin Elysia, e per ora sono questi due — stesso disegno, stesso livello di permessi, cambia solo come si aggancia il guard.
E se sono su un altro stack?
Sotto dà per scontato anche PostgreSQL. Su Django, Laravel o un'app Next.js che non sposterai, qui non c'è niente da installare: al massimo guardiamo l'auth che hai e ti diciamo cosa cambieremmo.
Devo stare per forza sulla piattaforma JAMflow?
No. Il modulo gira per conto suo, sulla tua infrastruttura, contro il tuo database. Alcune cose sono più strette quando il resto dello stack è nostro — il cluster Postgres, l'ingress da cui serviamo — ma nessuna di queste è una condizione.
Raccontaci come sono fatti i tuoi ruoli.
Descrivi come il tuo prodotto decide chi può fare cosa. Se il modulo lo copre già, te lo prendi. Se non lo copre, ti diciamo dritto cosa servirebbe — da parte di chi poi lo dovrebbe fare.






