Lewati ke konten utama

Autentikasi & Keamanan

Libre WebUI menggunakan akun pengguna lokal dengan sesi JWT. Instalasi baru selalu mengizinkan satu administrator lokal awal. Pendaftaran publik untuk semua akun lokal atau OAuth berikutnya ditutup secara bawaan.

Penyiapan Pertama Kali

Saat database belum memiliki pengguna:

  1. Libre WebUI menampilkan alur penyiapan pertama kali.
  2. Pengguna membuat akun lokal pertama.
  3. Akun diberi peran admin.
  4. Semua pendaftaran publik berikutnya tetap ditutup kecuali diaktifkan secara eksplisit.

Database yang sudah ada mempertahankan pengguna dan peran saat ini.

Akun Lokal

Pendaftaran lokal memerlukan:

  • Nama pengguna
  • Kata sandi antara 12 karakter dan 72 byte UTF-8, dengan huruf besar, huruf kecil, dan angka
  • Email opsional

Kata sandi di-hash dengan bcrypt sebelum disimpan. Rute login dan pendaftaran dibatasi lajunya.

Persetujuan Pendaftaran

Pendaftaran publik tidak langsung memberikan akses. Setiap akun yang dibuat melalui formulir pendaftaran publik atau penyedia OAuth dimulai dalam keadaan pending dan harus disetujui administrator sebelum dapat masuk.

Satu-satunya pengecualian adalah akun awal: akun nyata pertama pada database kosong dibuat secara atomik sebagai active dengan peran admin, sehingga instalasi baru tetap menghasilkan administrator yang berfungsi. Semua pendaftaran berikutnya menunggu peninjauan.

Yang dilihat pengguna tertunda:

  • Pendaftaran berhasil tetapi tidak mengembalikan token sesi. API merespons 202 dengan approvalRequired: true, dan UI menjelaskan bahwa administrator harus menyetujui akun.
  • Login dengan kata sandi dan kredensial benar ditolak dengan 403 serta kode ACCOUNT_PENDING ("Akun Anda sedang menunggu persetujuan administrator"). Login OAuth dialihkan kembali ke halaman login dengan ?approval=pending.
  • Status akun dibaca ulang dari database pada setiap permintaan terautentikasi, sehingga sesi tidak pernah dapat bertahan melampaui status active akun.

Yang dilihat administrator:

  • Pengelolaan pengguna menampilkan kartu Persetujuan tertunda yang mencantumkan akun menunggu, masing-masing dengan tindakan Aktifkan akun dan tindakan penolakan. Penolakan berarti penghapusan; tidak ada keadaan ditangguhkan yang terpisah.
  • Administrator menerima pemberitahuan dalam aplikasi saat masuk: lencana pada entri Pengguna dan toast saat pendaftaran baru tiba. Ringkasan persetujuan tertunda diperiksa sekitar sekali per menit (GET /api/users/pending-approvals, khusus administrator).
  • Persetujuan (PATCH /api/users/:id/approve, khusus administrator) mencatat administrator yang menyetujui akun dan waktunya. Persetujuan tidak mengubah peran: akun yang disetujui tetap memiliki peran user sampai dipromosikan administrator. Persetujuan berlaku pada upaya login pengguna berikutnya; tidak ada yang perlu dibuat ulang.

Akun yang sudah ada tidak terpengaruh oleh peningkatan: hanya akun yang dibuat melalui pendaftaran publik setelah fitur dirilis yang dimulai sebagai tertunda. Akun yang dibuat administrator dari pengelolaan pengguna langsung aktif.

Mengaktifkan Pendaftaran Publik dengan Sengaja

Pendaftaran dinonaktifkan secara bawaan. Tetapkan variabel lingkungan backend berikut hanya selama akun lokal atau OAuth baru perlu diterima:

ENABLE_SIGNUP=true

Kembalikan ke false setelah jangka waktu pendaftaran yang direncanakan. Pengguna lokal dan OAuth yang sudah ada tetap dapat masuk, dan administrator tetap dapat membuat akun dari pengelolaan pengguna saat pendaftaran publik ditutup.

Database kosong selalu mengizinkan satu administrator lokal, bahkan ketika ENABLE_SIGNUP=false; OAuth tidak dapat mengambil slot awal tersebut. Untuk deployment jarak jauh privat, tempatkan nama host di balik daftar izin identitas seperti Cloudflare Access sebelum memulai aplikasi, lalu buat administrator awal melalui rute terlindungi itu.

Peran

PeranTujuan
adminAdministrasi instans, pengelolaan pengguna, pengaturan sistem, dan operasi runtime Work tepercaya
userAlur kerja chat, model, persona, dokumen, dan pengaturan biasa

Instalasi, penghapusan, penyalinan, pendorongan, dan pembongkaran model dibatasi untuk administrator karena operasi ini mengubah sumber daya host.

Akses Work

Work dibatasi untuk administrator secara bawaan karena memungkinkan model terpilih mengeksekusi perintah sewenang-wenang di dalam kontainer terkelola. Administrator dapat membuka Work bagi semua pengguna aktif dari tab Manajemen Pengguna di Pengaturan; pengaturan ini bertahan setelah mulai ulang dan langsung berlaku, termasuk untuk sesi terminal terbuka. Ruang kerja folder host tetap khusus administrator dalam setiap mode karena melakukan bind-mount jalur server. Perlakukan setiap orang yang diberi akses Work sebagai operator runtime tepercaya, bukan hanya pengguna WebUI.

Otorisasi administrator diperiksa terhadap peran database saat ini, bukan hanya peran yang disimpan dalam cache JWT lama. Karena itu, menurunkan peran administrator langsung mencabut akses Work. Backend kemudian mencoba membatalkan proses aktif dan menghentikan kontainer serta pratinjau Work milik pengguna sambil mempertahankan rekaman tugas dan volume bernama. Jika pembersihan Docker gagal, akses tetap dicabut, perubahan peran melaporkan kegagalan pembersihan, dan operator harus memulihkan akses Docker lalu mengulangi pembersihan.

Menghapus pengguna bersifat destruktif terhadap data Work pengguna tersebut. Libre WebUI terlebih dahulu menghentikan kontainer terkelola dan menghapus volume Work mereka, lalu menghapus akun serta rekaman database. Jika Docker tidak dapat membuktikan pembersihan berhasil, penghapusan akun gagal agar administrator dapat memperbaiki masalah runtime dan mencoba lagi.

Grup dan Pemberian Akses Sumber Daya

Administrator dapat membuat grup dan mengelola keanggotaan dari tab Manajemen Pengguna di Pengaturan. Grup menjadi prinsipal untuk pemberian akses sumber daya: pemilik chat, catatan, dokumen, koleksi pengetahuan, folder, persona, prompt, keterampilan, atau kalender dapat memberikan akses read, write, atau admin kepada pengguna atau grup melalui API akses—setiap permukaan yang dapat dibagikan memakai dialog berbagi yang sama (lihat Berbagi)—dan administrator dapat membatasi server alat terdaftar kepada pengguna atau grup dengan cara yang sama. Sumber daya tetap privat secara bawaan—peran global admin tidak memberi akses ke konten pengguna lain. Keanggotaan dievaluasi saat permintaan, sehingga menghapus anggota langsung mencabut akses yang diperoleh dari grup. Tampilan "akses efektif" di tab Manajemen Pengguna dalam Pengaturan menjawab "mengapa pengguna ini dapat mengaksesnya?" dengan mencantumkan peran, grup, akses fitur, dan setiap izin yang menjangkaunya.

Log Audit Keamanan

Tindakan sensitif keamanan—login dan kegagalannya, logout, pencabutan sesi dan token, serta perubahan pengguna, grup, pemberian akses, dan token—dicatat dalam log audit khusus-tambah yang terpisah dari analitik penggunaan. Detail disunting sebelum disimpan: kunci yang menyerupai rahasia dibuang dan ukuran payload dibatasi, sehingga kata sandi, token, serta isi prompt tidak pernah masuk ke log. Mutasi grup dan pemberian akses menulis peristiwa auditnya dalam transaksi database yang sama, sehingga perubahan tidak dapat ada tanpa jejaknya. Administrator dapat mengueri log dari tab Manajemen Pengguna di Pengaturan; retensi bawaan adalah 180 hari (AUDIT_RETENTION_DAYS).

Sesi

Backend menandatangani JWT dengan JWT_SECRET. Tetapkan rahasia yang stabil dalam produksi:

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

Mengubah JWT_SECRET membatalkan sesi yang sudah ada. Token login lokal dan OAuth menggunakan JWT_EXPIRES_IN, yang nilai bawaannya 7d; perubahan nilai ini memengaruhi sesi baru. Koneksi WebSocket menukar token tahan lama dengan tiket sekali pakai berumur singkat dan ditutup ketika sesi dasarnya kedaluwarsa.

Setiap login juga membuat rekaman sesi sisi server yang diikat ke JWT. Pengaturan → Sesi mencantumkan setiap perangkat beserta metode login, aktivitas pertama dan terakhir, serta masa kedaluwarsa. Mencabut sesi di sana (atau "Keluar dari sesi lain") langsung membatalkan tokennya pada setiap replika dan menutup koneksi WebSocket aktifnya; logout mencabut sesi saat ini dengan cara yang sama. Token yang diterbitkan sebelum fitur ini tidak memiliki ID sesi dan tetap berlaku sampai kedaluwarsa, kecuali tindakan "keluar dari sesi lain" setelah login baru juga menetapkan batas per akun yang menolaknya.

Autentikasi Dua Faktor dan Passkey

Pengaturan → Sesi mengelola faktor kedua dan login tanpa kata sandi:

  • Aplikasi autentikator (TOTP). Pendaftaran menampilkan rahasia base32 dan tautan otpauth:// untuk aplikasi autentikator mana pun; mengonfirmasi kode 6 digit pertama mengaktifkannya dan menampilkan sepuluh kode pemulihan sekali pakai. Setelah itu, login dengan kata sandi mengembalikan tantangan berumur singkat alih-alih sesi, dan POST /api/auth/mfa/verify menyelesaikan login dengan kode TOTP atau kode pemulihan. Langkah waktu setiap kode yang diterima dicatat agar kode yang disadap tidak dapat diputar ulang; kode pemulihan hanya disimpan sebagai token pencarian satu arah berkunci dan masing-masing berfungsi tepat sekali. Menonaktifkan atau membuat ulang kode pemulihan memerlukan pembuktian ulang faktor.
  • Passkey (WebAuthn). "Masuk dengan passkey" melakukan login tanpa kata sandi menggunakan kredensial yang dapat ditemukan; verifikasi pengguna (kunci layar, biometrik, atau PIN) diperlukan saat pendaftaran dan login. Atestasi diterima sebagai none, kredensial ES256 dan EdDSA didukung, dan materi kredensial dienkripsi saat disimpan dengan ID dipertahankan sebagai token pencarian berkunci. Tantangan hanya dapat digunakan sekali dan kedaluwarsa setelah lima menit; penghitung tanda tangan bukan nol yang tidak bertambah ditolak sebagai tanda kloning. Passkey memerlukan origin aman (HTTPS), atau localhost dalam pengembangan; tetapkan WEBAUTHN_RP_ID jika instans diakses melalui lebih dari satu nama host.

Token tantangan MFA yang diterbitkan setelah kata sandi benar ditandatangani dengan rahasia yang diturunkan dari (tetapi berbeda dengan) JWT_SECRET: token ini tidak pernah dapat mengautentikasi permintaan API, terikat pada satu akun dan satu tujuan, lalu digunakan habis saat berhasil.

Administrator dapat mewajibkan faktor kedua bagi setiap akun (Pengguna → kartu kebijakan dua faktor, atau kunci dengan MFA_REQUIRED_MODE=required). Pengguna yang belum memilikinya dipandu melalui pendaftaran pada login berikutnya sebelum sesi diterbitkan. Administrator juga dapat mengatur ulang pendaftaran TOTP pengguna dari daftar pengguna untuk pemulihan akun; passkey dibiarkan karena dikelola pengguna dari pengaturan. Pendaftaran, aktivasi, kegagalan verifikasi, penonaktifan, perubahan kebijakan, pendaftaran/penghapusan passkey, dan pengaturan ulang oleh administrator semuanya dicatat dalam log audit keamanan.

MFA berlaku untuk login dengan kata sandi. Login OAuth dan OIDC mengandalkan faktor kedua milik penyedia identitas dan tidak ditantang lagi. Token API tidak terpengaruh karena tidak pernah menggunakan autentikasi sesi.

Token API

Pengaturan → Kunci API menerbitkan token akses pribadi (prefiks lwk_) untuk penggunaan programatis. Rahasia hanya ditampilkan sekali dan disimpan sebagai hash. Setiap token membawa daftar cakupan eksplisit (chat, models, documents, notes, personas, media, work, admin); backend memetakan setiap keluarga rute ke cakupan yang diperlukan, sehingga token khusus catatan tidak dapat menyentuh chat atau administrasi, dan pengelolaan sesi tidak pernah dapat diakses dengan token. Token mendukung masa kedaluwarsa opsional, melacak penggunaan terakhir, dapat dicabut kapan saja, dan dibatasi lajunya per token di seluruh replika. Token bercakupan admin hanya dapat diterbitkan administrator dan tetap mengharuskan akun memiliki peran admin saat digunakan. Token bercakupan chat juga menjadi kunci untuk API /v1 publik yang kompatibel dengan OpenAI.

Cloudflare Turnstile

Turnstile melindungi login dan pendaftaran dengan kata sandi ketika kedua kunci dikonfigurasi:

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

Frontend menetapkan tindakan login dan signup yang berbeda. Backend memverifikasi token dengan Cloudflare dan menolak respons jika nama host atau tindakannya tidak cocok dengan permintaan. BASE_URL menyediakan nama host yang diharapkan ketika TURNSTILE_EXPECTED_HOSTNAME tidak ditetapkan secara eksplisit.

Jika salah satu kunci tidak tersedia, Turnstile dinonaktifkan.

GitHub OAuth

Konfigurasikan:

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

Alur GitHub OAuth membuat pengguna lokal dengan nama pengguna berprefiks gh_ dan menetapkan peran user secara bawaan.

Hugging Face OAuth

Konfigurasikan:

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

Alur Hugging Face OAuth membuat pengguna lokal dengan nama pengguna berprefiks hf_ dan menetapkan peran user secara bawaan.

Kedua penyedia OAuth menggunakan nilai state acak secara kriptografis yang diikat pada cookie HttpOnly dan SameSite berumur singkat. Callback menolak state yang tidak ada atau tidak cocok. Setelah callback berhasil, JWT kembali ke frontend dalam cookie HttpOnly 60 detik yang langsung ditukar dan dihapus; token bearer tidak pernah ditempatkan dalam URL callback, riwayat peramban, atau header perujuk.

Pengalihan dan CORS

Tetapkan BASE_URL untuk nilai bawaan callback dan CORS_ORIGIN untuk akses peramban:

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

Untuk pengembangan lokal, sertakan origin pengembangan Vite:

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

Mode Demo

Mode demo adalah mode pratinjau frontend. Mode ini mengisi kredensial demo yang dinonaktifkan dan menggunakan respons API tiruan. Mode demo bukan mode autentikasi produksi.

Daftar Periksa Keamanan

  • Tetapkan JWT_SECRET yang kuat.
  • Simpan DATA_DIR pada penyimpanan persisten dengan kontrol akses.
  • Cadangkan ENCRYPTION_KEY bersama database.
  • Konfigurasikan Turnstile untuk pendaftaran publik.
  • Gunakan HTTPS untuk deployment publik.
  • Batasi kunci API penyedia pada cakupan minimum yang diperlukan.
  • Pastikan URL callback OAuth tepat.
  • Berikan akses Work (akun administrator atau mode terbuka bagi semua pengguna) hanya kepada orang yang dipercaya untuk mengoperasikan runtime kontainer backend.

Dokumentasi Terkait