Sari la conținutul principal

Autentificare și securitate

Libre WebUI folosește conturi locale de utilizator cu sesiuni JWT. O instalare nouă permite întotdeauna inițializarea unui administrator local. Înregistrarea publică pentru toate conturile locale sau OAuth ulterioare este închisă implicit.

Configurarea inițială

Când baza de date nu are utilizatori:

  1. Libre WebUI afișează fluxul de configurare inițială.
  2. Utilizatorul creează primul cont local.
  3. Contului i se atribuie rolul admin.
  4. Toate înregistrările publice ulterioare rămân închise dacă nu sunt activate explicit.

Bazele de date existente își păstrează utilizatorii și rolurile actuale.

Conturi locale

Înregistrarea locală necesită:

  • Nume de utilizator
  • Parolă între 12 caractere și 72 de octeți UTF-8, cu o literă mare, una mică și un număr
  • E-mail opțional

Parolele sunt transformate în hash cu bcrypt înainte de stocare. Rutele de autentificare și înregistrare au limitare de rată.

Aprobarea înregistrării

Înregistrarea publică nu acordă acces de la sine. Fiecare cont creat prin formularul public de înregistrare sau printr-un furnizor OAuth începe în starea pending și trebuie aprobat de un administrator înainte de autentificare.

Singura excepție este inițializarea: primul cont real dintr-o bază de date goală este creat atomic ca active cu rolul admin, astfel încât o instalare nouă să obțină un administrator funcțional. Toate înregistrările ulterioare așteaptă verificarea.

Ce vede un utilizator în așteptare:

  • Înregistrarea reușește, dar nu returnează un token de sesiune. API-ul răspunde 202 cu approvalRequired: true, iar interfața explică faptul că un administrator trebuie să aprobe contul.
  • Autentificarea cu parolă și credențiale corecte este refuzată cu 403 și codul ACCOUNT_PENDING ("Your account is waiting for administrator approval"). Autentificarea OAuth redirecționează înapoi la pagina de conectare cu ?approval=pending.
  • Starea contului este recitită din baza de date la fiecare cerere autentificată, astfel încât o sesiune nu poate depăși niciodată starea active a contului.

Ce vede un administrator:

  • Gestionarea utilizatorilor afișează un card Aprobări în așteptare cu conturile care așteaptă, fiecare având acțiunile Activează contul și respingere. Respingerea înseamnă ștergere; nu există o stare suspendată separată.
  • Administratorii sunt notificați în aplicație cât timp sunt autentificați: apare o insignă la intrarea Utilizatori și o notificare când sosesc înregistrări noi. Rezumatul aprobărilor în așteptare este verificat aproximativ o dată pe minut (GET /api/users/pending-approvals, numai administratori).
  • Aprobarea (PATCH /api/users/:id/approve, numai administratori) înregistrează administratorul care a aprobat contul și momentul aprobării. Nu schimbă rolul: conturile aprobate păstrează rolul user până când un administrator le promovează. Aprobarea intră în vigoare la următoarea încercare de autentificare a utilizatorului; nu trebuie recreat nimic.

Conturile existente nu sunt afectate de actualizare: numai conturile create prin înregistrarea publică după lansarea funcției încep în așteptare. Conturile create de un administrator din Gestionarea utilizatorilor sunt active imediat.

Activarea intenționată a înregistrării publice

Înregistrarea este dezactivată implicit. Setați variabila de mediu backend de mai jos numai în perioada în care trebuie acceptate conturi locale sau OAuth noi:

ENABLE_SIGNUP=true

Readuceți-o la false după orice perioadă planificată de înregistrare. Utilizatorii locali și OAuth existenți se pot autentifica în continuare, iar administratorii pot crea conturi din Gestionarea utilizatorilor cât timp înregistrarea publică este închisă.

O bază de date goală permite întotdeauna un administrator local, chiar și cu ENABLE_SIGNUP=false; OAuth nu poate ocupa acel loc de inițializare. Pentru o implementare privată la distanță, puneți numele gazdei în spatele unei liste de identități permise, precum Cloudflare Access, înainte de pornirea aplicației, apoi creați administratorul inițial prin ruta protejată.

Roluri

RolScop
adminAdministrarea instanței, utilizatorilor și setărilor de sistem și operarea de încredere a runtime-ului Work
userFluxuri obișnuite pentru chat, modele, personaje, documente și setări

Instalarea, ștergerea, copierea, publicarea și descărcarea modelelor sunt limitate la administratori, deoarece aceste operații schimbă resursele gazdei.

Acces Work

Work este limitat implicit la administratori deoarece permite unui model selectat să execute comenzi arbitrare într-un container gestionat. Un administrator poate deschide Work tuturor utilizatorilor activi din fila Gestionarea utilizatorilor din Setări; setarea persistă după repornire și intră imediat în vigoare, inclusiv pentru sesiunile de terminal deschise. Spațiile de lucru bazate pe dosare ale gazdei rămân disponibile numai administratorilor în orice mod, deoarece montează căi ale serverului. Tratați orice persoană cu acces Work ca operator de încredere al runtime-ului, nu doar ca utilizator WebUI.

Autorizarea de administrator este verificată față de rolul curent din baza de date, nu numai față de rolul memorat într-un JWT existent. Retrogradarea unui administrator revocă imediat accesul Work. Backend-ul încearcă apoi să anuleze execuțiile active și să oprească containerele Work și previzualizările utilizatorului, păstrând înregistrările sarcinilor și volumele denumite. Dacă curățarea Docker eșuează, accesul rămâne revocat, schimbarea rolului raportează eroarea, iar operatorul trebuie să restaureze accesul Docker și să reîncerce curățarea.

Ștergerea unui utilizator distruge datele Work ale acestuia. Libre WebUI oprește mai întâi containerele gestionate și elimină volumele Work, apoi șterge contul și înregistrările bazei de date. Dacă Docker nu poate dovedi că operația de curățare a reușit, ștergerea contului eșuează, astfel încât un administrator să poată corecta problema runtime-ului și să reîncerce.

Grupuri și permisiuni pentru resurse

Administratorii pot crea grupuri și gestiona membrii din fila Gestionarea utilizatorilor din Setări. Grupurile sunt entități pentru permisiunile resurselor: proprietarul unui chat, al unei notițe, al unui document, al unei colecții de cunoștințe, al unui dosar, al unui personaj, al unui prompt, al unei abilități sau al unui calendar poate acorda acces read, write sau admin unui utilizator sau grup prin API-ul de acces — toate suprafețele partajabile folosesc același dialog de partajare (consultați Partajare) — iar administratorii pot limita în același mod serverele de instrumente înregistrate la utilizatori sau grupuri. Resursele rămân private implicit — rolul global admin nu acordă acces la conținutul altor utilizatori. Apartenența este evaluată la momentul cererii, astfel încât eliminarea unui membru revocă imediat accesul acordat prin grup. Vizualizarea „acces efectiv” din fila Gestionarea utilizatorilor din Setări răspunde la întrebarea „de ce poate acest utilizator accesa resursa?” prin listarea rolului, grupurilor, accesului la funcții și tuturor permisiunilor care îl vizează.

Jurnal de audit de securitate

Acțiunile sensibile din punct de vedere al securității — autentificări și eșecuri, deconectări, revocări de sesiuni și tokenuri, modificări ale utilizatorilor, grupurilor, permisiunilor și tokenurilor — sunt înregistrate într-un jurnal de audit numai pentru adăugare, separat de analiza utilizării. Detaliile sunt cenzurate înainte de stocare: cheile care seamănă cu secrete sunt eliminate și dimensiunile conținutului sunt limitate, astfel încât parolele, tokenurile și conținutul prompturilor nu intră niciodată în jurnal. Modificările grupurilor și permisiunilor își scriu evenimentul de audit în aceeași tranzacție a bazei de date, astfel încât o schimbare să nu poată exista fără urmă. Administratorii pot interoga jurnalul din fila Gestionarea utilizatorilor din Setări; păstrarea implicită este de 180 de zile (AUDIT_RETENTION_DAYS).

Sesiuni

Backend-ul semnează JWT-urile cu JWT_SECRET. Setați un secret stabil în producție:

JWT_SECRET=replace-with-a-long-random-secret

Schimbarea JWT_SECRET invalidează sesiunile existente. Tokenurile de autentificare locală și OAuth folosesc JWT_EXPIRES_IN, cu valoarea implicită 7d; schimbarea acestei valori afectează sesiunile noi. Conexiunile WebSocket schimbă tokenul persistent cu un bilet de unică folosință, cu durată scurtă, și se închid când expiră sesiunea subiacentă.

Fiecare autentificare creează și o înregistrare de sesiune pe server, legată în JWT. Setări → Sesiuni listează fiecare dispozitiv cu metoda de autentificare, prima și ultima activitate și expirarea. Revocarea unei sesiuni de acolo (sau „Deconectează celelalte sesiuni”) invalidează imediat tokenul pe fiecare replică și închide conexiunile WebSocket active; deconectarea revocă sesiunea curentă în același mod. Tokenurile emise înaintea acestei funcții nu au id de sesiune și rămân valabile până la expirare, cu excepția cazului în care „deconectează celelalte sesiuni” după o autentificare nouă setează și un prag per cont care le respinge.

Autentificare în doi pași și passkeys

Setări → Sesiuni gestionează atât al doilea factor, cât și autentificarea fără parolă:

  • Aplicație de autentificare (TOTP). Înregistrarea afișează un secret base32 și un link otpauth:// pentru orice aplicație de autentificare; confirmarea primului cod de 6 cifre o activează și dezvăluie zece coduri de recuperare de unică folosință. După aceea, autentificarea cu parolă returnează o provocare de scurtă durată în locul unei sesiuni, iar POST /api/auth/mfa/verify finalizează autentificarea cu un cod TOTP sau de recuperare. Este înregistrat pasul temporal al fiecărui cod acceptat, astfel încât un cod interceptat să nu poată fi reutilizat; codurile de recuperare sunt stocate numai ca tokenuri de căutare unidirecționale cu cheie și fiecare funcționează exact o dată. Dezactivarea sau regenerarea codurilor de recuperare necesită dovedirea din nou a unui factor.
  • Passkeys (WebAuthn). „Autentificare cu passkey” realizează o autentificare fără parolă cu o credențială detectabilă; verificarea utilizatorului (blocarea ecranului, date biometrice sau PIN) este obligatorie la înregistrare și autentificare. Atestarea este acceptată ca none, sunt acceptate credențialele ES256 și EdDSA, iar materialul credențial este criptat în repaus, cu id-ul păstrat ca token de căutare cu cheie. Provocările sunt de unică folosință și expiră după cinci minute; un contor de semnături nenul care nu avansează este respins ca semnal de clonare. Passkeys necesită o origine sigură (HTTPS) sau localhost în dezvoltare; setați WEBAUTHN_RP_ID când instanța este accesată prin mai multe nume de gazdă.

Tokenul de provocare MFA emis după o parolă corectă este semnat cu un secret derivat din JWT_SECRET, dar distinct de acesta: nu poate autentifica niciodată o cerere API, este legat de un singur cont și un singur scop și este consumat la reușită.

Administratorii pot impune un al doilea factor pentru fiecare cont (Utilizatori → cardul politicii în doi pași sau fixați-l cu MFA_REQUIRED_MODE=required). Utilizatorii fără unul sunt ghidați prin înregistrare la următoarea autentificare, înainte de emiterea sesiunii. Administratorii pot reseta și înregistrarea TOTP a unui utilizator din lista de utilizatori pentru recuperarea contului; passkeys rămân, deoarece utilizatorul le gestionează din setări. Înregistrarea, activarea, eșecurile verificării, dezactivarea, schimbările politicii, înregistrarea/eliminarea passkey și resetările administratorilor sunt consemnate în jurnalul de audit de securitate.

MFA se aplică autentificărilor cu parolă. Autentificările OAuth și OIDC se bazează pe al doilea factor al furnizorului de identitate și nu sunt provocate din nou. Tokenurile API nu sunt afectate: nu folosesc niciodată autentificarea sesiunii.

Tokenuri API

Setări → Chei API emite tokenuri de acces personale (prefix lwk_) pentru utilizare programatică. Secretul este afișat o singură dată și stocat numai ca hash. Fiecare token are o listă explicită de domenii (chat, models, documents, notes, personas, media, work, admin); backend-ul mapează fiecare familie de rute la un domeniu obligatoriu, astfel încât un token numai pentru notițe nu poate accesa chaturile sau administrarea, iar gestionarea sesiunilor nu este niciodată accesibilă prin token. Tokenurile acceptă expirare opțională, urmăresc ultima utilizare, pot fi revocate oricând și au limitare de rată per token în toate replicile. Tokenurile cu domeniu admin pot fi emise numai de administratori și necesită în continuare ca acel cont să aibă rolul admin la utilizare. Un token cu domeniul chat este și cheia pentru API-ul public /v1 compatibil cu OpenAI.

Cloudflare Turnstile

Turnstile protejează autentificarea și înregistrarea cu parolă atunci când ambele chei sunt configurate:

TURNSTILE_SITE_KEY=...
TURNSTILE_SECRET_KEY=...
TURNSTILE_EXPECTED_HOSTNAME=chat.example.com

Frontend-ul atribuie acțiuni distincte login și signup. Backend-ul verifică tokenul prin Cloudflare și respinge un răspuns al cărui nume de gazdă sau acțiune nu corespunde cererii. BASE_URL furnizează numele de gazdă așteptat când TURNSTILE_EXPECTED_HOSTNAME nu este setat explicit.

Dacă lipsește oricare dintre chei, Turnstile este dezactivat.

GitHub OAuth

Configurați:

GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_CALLBACK_URL=https://your-domain.example/api/auth/oauth/github/callback

Fluxul GitHub OAuth creează utilizatori locali cu nume prefixate cu gh_ și atribuie implicit rolul user.

Hugging Face OAuth

Configurați:

HUGGINGFACE_CLIENT_ID=...
HUGGINGFACE_CLIENT_SECRET=...
HUGGINGFACE_CALLBACK_URL=https://your-domain.example/api/auth/oauth/huggingface/callback

Fluxul Hugging Face OAuth creează utilizatori locali cu nume prefixate cu hf_ și atribuie implicit rolul user.

Ambii furnizori OAuth folosesc o valoare state criptografic aleatoare, legată de un cookie HttpOnly, SameSite de scurtă durată. Callback-ul respinge o stare absentă sau necorespunzătoare. După un callback reușit, JWT-ul revine în frontend într-un cookie HttpOnly de 60 de secunde, care este schimbat și șters imediat; tokenurile bearer nu sunt plasate niciodată în URL-uri callback, istoricul browserului sau antete referrer.

Redirecționări și CORS

Setați BASE_URL pentru valorile callback implicite și CORS_ORIGIN pentru acces din browser:

BASE_URL=https://your-domain.example
CORS_ORIGIN=https://your-domain.example

Pentru dezvoltare locală, includeți originea de dezvoltare Vite:

CORS_ORIGIN=http://localhost:5173,http://127.0.0.1:5173

Mod demonstrativ

Modul demonstrativ este un mod de previzualizare frontend. Precompletează credențiale demonstrative dezactivate și folosește răspunsuri API simulate. Nu este un mod de autentificare pentru producție.

Listă de verificare a securității

  • Setați un JWT_SECRET puternic.
  • Păstrați DATA_DIR într-un spațiu persistent cu control al accesului.
  • Creați o copie de rezervă a ENCRYPTION_KEY împreună cu baza de date.
  • Configurați Turnstile pentru înregistrarea publică.
  • Folosiți HTTPS pentru implementările publice.
  • Limitați cheile API ale furnizorilor la domeniul minim necesar.
  • Păstrați exacte URL-urile callback OAuth.
  • Acordați acces Work (conturi de administrator sau modul deschis tuturor utilizatorilor) numai persoanelor de încredere pentru operarea runtime-ului de containere al backend-ului.

Documentație conexă