Autenticazione e sicurezza
Libre WebUI usa account locali con sessioni JWT. Un'installazione nuova consente sempre di creare un amministratore locale. La registrazione pubblica per tutti gli account locali o OAuth successivi è chiusa per impostazione predefinita.
Prima configurazione
Quando il database non ha utenti:
- Libre WebUI mostra il flusso iniziale.
- L'utente crea il primo account locale.
- L'account riceve il ruolo
admin. - Tutte le registrazioni successive restano chiuse finché non abilitate esplicitamente.
I database esistenti mantengono utenti e ruoli.
Account locali
La registrazione richiede:
- Nome utente
- Password tra 12 caratteri e 72 byte UTF-8, con maiuscola, minuscola e numero
- Email opzionale
Le password sono salvate con hash bcrypt. Login e registrazione sono rate-limited.
Approvazione delle registrazioni
Registrarsi non concede accesso. Ogni account creato dal modulo o OAuth parte in pending e richiede approvazione admin.
L'unica eccezione è il bootstrap: il primo account reale in un database vuoto viene creato atomicamente active con ruolo admin. Tutti gli altri attendono.
L'utente in attesa vede:
- risposta
202conapprovalRequired: true, senza token, e spiegazione nella UI; - login corretto rifiutato con
403eACCOUNT_PENDING("Il tuo account attende l'approvazione dell'amministratore"); OAuth torna con?approval=pending; - lo stato viene riletto a ogni richiesta, quindi una sessione non sopravvive allo stato
active.
L'amministratore vede:
- scheda Approvazioni in attesa con Attiva account e rifiuta. Rifiutare elimina; non esiste sospensione separata;
- badge e toast. Il riepilogo è interrogato circa ogni minuto (
GET /api/users/pending-approvals); - approvazione con
PATCH /api/users/:id/approve, che registra chi/quando senza cambiare ruolo: rimaneuserfinché promosso.
Gli account precedenti non cambiano. Quelli creati da un amministratore sono subito attivi.
Abilitare deliberatamente la registrazione
ENABLE_SIGNUP=true
Usala solo nella finestra prevista e poi torna a false. Gli utenti esistenti accedono comunque e gli admin possono creare account.
Un database vuoto permette sempre un amministratore locale anche con ENABLE_SIGNUP=false; OAuth non può occupare quel posto. In remoto, proteggi il nome host con una lista di identità come Cloudflare Access prima di avviare.
Ruoli
| Ruolo | Scopo |
|---|---|
admin | Amministrazione dell'istanza, utenti, sistema e runtime Work affidabile |
user | Flussi normali di chat, modelli, personas, documenti e impostazioni |
Installazione, eliminazione, copia, push e unload dei modelli sono riservati agli admin perché cambiano risorse dell'host.
Accesso Work
Work è admin-only per impostazione predefinita perché consente comandi arbitrari in container gestiti. Un amministratore può aprirlo a tutti gli utenti attivi; la configurazione persiste e si applica subito, anche ai terminali aperti. Gli spazi basati su cartelle dell'host restano admin-only. Considera chiunque abbia accesso un operatore affidabile.
L'autorizzazione legge il ruolo attuale nel database, non soltanto il JWT. Il downgrade revoca subito; il backend prova ad abortire esecuzioni e fermare container/anteprime preservando record e volumi. Se la pulizia Docker fallisce, l'accesso resta revocato e l'errore viene segnalato.
Eliminare un utente distrugge i suoi dati Work. Prima ferma container e rimuove volumi; se non può provarlo, l'eliminazione fallisce per consentire la correzione.
Gruppi e autorizzazioni
Gli admin creano gruppi e membri. I gruppi sono principali per le concessioni: il proprietario di chat, nota, documento, raccolta, cartella, persona, prompt, abilità o calendario può concedere read, write o admin a utenti/gruppi. Tutte le superfici usano lo stesso dialogo (Condivisione); anche server di strumenti possono essere limitati. Le risorse sono private per default e il ruolo globale admin non dà accesso ai contenuti altrui. L'appartenenza viene valutata a ogni richiesta. La vista di accesso effettivo elenca ruolo, gruppi, funzioni e concessioni.
Log di audit di sicurezza
Login e fallimenti, logout, revoche e modifiche a utenti, gruppi, concessioni e token sono registrati in un log append-only separato dall'uso. I dettagli vengono redatti: chiavi sensibili eliminate e dimensioni limitate, così password, token e prompt non entrano. Mutazioni di gruppi e concessioni scrivono l'evento nella stessa transazione. Retention predefinita 180 giorni (AUDIT_RETENTION_DAYS).
Sessioni
JWT_SECRET=replace-with-a-long-random-secret
Cambiare JWT_SECRET invalida le sessioni. I token usano JWT_EXPIRES_IN, default 7d; la modifica vale per nuove sessioni. WebSocket scambia il token duraturo con un ticket breve e monouso e chiude alla scadenza.
Ogni login crea un record server-side legato al JWT. Impostazioni → Sessioni mostra dispositivo, metodo, attività e scadenza. Revocare o "Esci dalle altre sessioni" invalida subito su tutte le repliche e chiude WebSocket; logout revoca quella attuale. I token vecchi senza ID durano fino a scadenza, salvo cutoff per account impostato da "esci dalle altre".
Autenticazione a due fattori e passkey
- App autenticatore (TOTP). L'iscrizione mostra segreto base32 e link
otpauth://; il primo codice a 6 cifre attiva e mostra dieci codici di recupero. Poi il login restituisce una challenge breve ePOST /api/auth/mfa/verifyconclude con TOTP o recupero. Il timestep accettato viene registrato, i codici di recupero sono token unidirezionali e monouso. Disattivare o rigenerare richiede dimostrare un fattore. - Passkey (WebAuthn). Accesso senza password con credenziale individuabile e verifica utente (blocco, biometria o PIN). Attestation
none, ES256 ed EdDSA supportati; materiale cifrato e ID come token di ricerca. Challenge monouso di cinque minuti; contatore non zero che non avanza è segnale di clone. Richiede HTTPS olocalhost; usaWEBAUTHN_RP_IDper più host.
Il token MFA dopo password è firmato con segreto derivato ma distinto da JWT_SECRET, non autentica API, è legato a un account/scopo e consumato al successo.
Gli admin possono imporlo a tutti (scheda Utenti o MFA_REQUIRED_MODE=required). Chi non lo ha viene guidato al prossimo login. L'admin può resettare TOTP; le passkey restano all'utente. Tutti gli eventi sono auditati.
MFA vale per password. OAuth/OIDC si affidano al provider e i token API non sono interessati.
Token API
Impostazioni → Chiavi API crea token personali con prefisso lwk_. Il segreto appare una volta e viene salvato solo come hash. Ogni token ha scope (chat, models, documents, notes, personas, media, work, admin); ogni famiglia di rotte richiede lo scope, e la gestione sessioni non è accessibile. Possono scadere, registrano l'ultimo uso, sono revocabili e rate-limited tra repliche. Token admin richiedono amministratore anche all'uso. Lo scope chat serve anche alla API pubblica /v1 compatibile OpenAI.
Cloudflare Turnstile
TURNSTILE_SITE_KEY=...
TURNSTILE_SECRET_KEY=...
TURNSTILE_EXPECTED_HOSTNAME=chat.example.com
Il frontend assegna azioni login e signup. Il backend verifica con Cloudflare e rifiuta hostname/azione diversi. BASE_URL fornisce l'host quando TURNSTILE_EXPECTED_HOSTNAME non è impostato. Senza una chiave, è disabilitato.
GitHub OAuth
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_CALLBACK_URL=https://your-domain.example/api/auth/oauth/github/callback
Crea utenti locali con prefisso gh_ e ruolo user.
Hugging Face OAuth
HUGGINGFACE_CLIENT_ID=...
HUGGINGFACE_CLIENT_SECRET=...
HUGGINGFACE_CALLBACK_URL=https://your-domain.example/api/auth/oauth/huggingface/callback
Crea utenti locali con prefisso hf_ e ruolo user.
Entrambi usano state casuale legato a cookie HttpOnly SameSite breve. Callback mancante o diverso viene rifiutato. Il JWT torna in un cookie HttpOnly di 60 secondi, scambiato e cancellato; Bearer non entra in URL, cronologia o referrer.
Redirect e CORS
Imposta CORS_ORIGIN per consentire l'accesso dal browser:
BASE_URL=https://your-domain.example
CORS_ORIGIN=https://your-domain.example
In sviluppo:
CORS_ORIGIN=http://localhost:5173,http://127.0.0.1:5173
Modalità demo
È una modalità di anteprima frontend con credenziali precompilate e API simulate. Non è autenticazione di produzione.
Checklist di sicurezza
- Usa
JWT_SECRETforte. - Mantieni
DATA_DIRpersistente e protetto. - Esegui backup di
ENCRYPTION_KEY. - Configura Turnstile per registrazione pubblica.
- Usa HTTPS.
- Limita chiavi dei provider.
- Mantieni esatti i callback OAuth.
- Concedi Work solo a operatori affidabili.