Work: spații de lucru izolate
Work este suprafața nativă pentru agenți de cod. Fiecare task combină conversație
persistentă, rută explicită de provider și filesystem dedicat la /workspace. Modelul
inspectează/editează fișiere, rulează comenzi într-un container Docker sau Pod Kubernetes
per task și pornește preview în browser. Nu cere Libre Claw sau daemon separat.
Orice API Work cere cont autentificat cu acces. Implicit doar admins; administratorul poate deschide tuturor activi, dar host-folder rămâne admin-only fiindcă montează căi server. Work permite deliberat comenzi shell arbitrare în sandbox și egress dacă policy nu îl oprește. Tratați orice utilizator ca operator runtime de încredere.
Noutăți release
- Acțiuni Work și Chat separate în sidebar.
- Taskuri în sidebar normal cu poziții stabile și ștergere directă.
- Identitate sandbox și volume Docker/PVC persistent per task; containerul poate fi recreat fără pierderea fișierelor.
- Conversație, stare run, tool activity, model și ownership persistente în bază.
- Stream autentificat pentru text, reasoning expus, tools/results, usage, skills și stare.
- Skills server-owned pentru inspect/edit/verify/preview fără control files în proiect.
- Ollama local/Cloud cu tools și pluginuri provider.
- Split Conversation/Workspace responsive, draggable și keyboard-accessible.
- Files, Activity, Git, Terminal, Preview și Screen — Work Computer observabil și învățabil.
- Syntax light/dark, formatting, conflict detection și drafts.
- Disclosure dismissible per utilizator pentru remote provider.
- Traduceri Work în 25 locale, cu Arabic RTL și cod/căi/IDs/output LTR.
Unitatea persistentă este workspace-ul, nu containerul continuu. Libre pornește/oprește/recreează, păstrând volumul.
Arhitectură
Libre, nu model/browser, alege numele, image, mount, user, limits, network și preview port. Modelul primește numai:
list_filesread_filewrite_filedelete_filemove_filesearch_filesrun_commandstart_previewstop_preview
delete_file/move_file sunt path-guarded: nu ies, nu urmează symlink, cer flag
recursive pentru director și nu suprascriu destinația. Prin file helper funcționează și
când preview rulează iar run_command este blocat.
Cererile model vin din backend, nu container și nu depind de policy network.
Cerințe
- Docker backend: Docker și daemon accesibil, permisiune la
dockersauWORK_DOCKER_COMMAND. - Kubernetes: credentiale API, Role/RoleBinding, namespace și NetworkPolicies Helm cu
work.enabled=true. - Model cu tools prin Ollama sănătos/Cloud sau plugin activ cu model exact și credentiale admin.
- Storage pentru image, proiecte, dependencies și cont autentificat cu acces.
Libre verifică Ollama capability tools; fără aceasta refuză. Pluginul trebuie să
suporte protocolul. Respingerea remote eșuează fără schimbare silențioasă.
Pornire locală
docker info
npx libre-webui@latest
Deschideți http://localhost:8080, login admin, Work, model și descriere. Fără Docker,
apare Runtime unavailable, Run dezactivat și niciodată fallback la host. Image-ul se
inspectează/descarcă la prima folosire, deci prima operație poate dura.
Interfața Work
Creare și revenire
Alegeți Work, instrucțiune, model, Run. Primul mesaj creează task, run, rută și workspace. Taskul rămâne în sidebar; redeschiderea restaurează conversația, Files și selecția. Mesajele vechi se încarcă pe pagini. Redenumire/ștergere din meniu. Un singur run activ; următoarea instrucțiune folosește aceeași conversație/filesystem.
Composerul oferă dictare prin browser speech sau STT provider și adaugă transcriptul. Fișierele create/mutate apar chips sub tool activity; click deschide Files și schimbă suprafața pe ecrane înguste. Numai tools mutatoare produc chips.
Angajarea unui agent
Cu personaje, Hire as an agent creează agent numit persistent. Persona rămâne între runs; numele/system prompt precedă promptul Work, dar contractul sandbox domină. Agents sunt fixați în grupul Agents cu avatar, activity și status. Când bara laterală este compactă, în șină rămân doar acele avataruri fixate; sarcinile Work ocazionale reapar când bara este extinsă.
Statusul are două niveluri. Pentru agent, un call ieftin fără tools cere ~8 cuvinte
("Inbox at zero. 2 replies ready."), max o linie 90 caractere. Failure/timeout folosește
prima linie finală. Ad hoc și failed doar deterministic, iar
WORK_STATUS_BLURB_MODEL=0 oprește call. Indicatorul unread folosește marker monoton
sincronizat și arată punct când run terminal este după marker.
Notificările: work-run-finished, work-run-attention,
work-takeover. Bannerul este numai pe Screen, push ajunge în altă parte și linkul deschide agentul.
Puteți angaja persona proprie sau shared fără memoriile ownerului. Dacă se șterge,
agentul continuă cu warning. API acceptă personaId și isAgent; persona înseamnă agent.
Fila Agent
- Identity: avatar, nume, activity, status.
- Screen: cu Work Computer, thumbnail live view-only, viewer real în buget; click deschide Screen complet cu takeover/teach/audio.
- Routines: automations legate de task. Fiecare fire folosește
același workspace/conversation/model/runtime, nu task nou. Rânduri cu schedule și
pause/resume, formular + Routine deja bound. Dacă agentul e ocupat,
work-task-busy, nu queue. - Auto Review: comutatorul de aprobări al agentului și regulile Always-allow strânse de el (ștergerea unei reguli îi închide la loc domeniul). Când politica task-ului impune revizuirea, comutatorul rămâne blocat pe pornit.
- Taught skills cu enable/disable.
Instrumente conectate (servere MCP și OpenAPI)
Agenții Work pot apela aceleași servere de instrumente configurate pentru
chat — MCP sau OpenAPI, înregistrate de administrator în Setări → Instrumente. Agentului îi
apar sub numele lor cu prefix de spațiu (server__tool), iar apelurile rulează din backend-ul
Libre WebUI prin gateway-ul întărit de instrumente (ieșire protejată împotriva SSRF, credențiale
per utilizator, limite de dimensiune și timp), niciodată din interiorul sandboxului.
Oferta este onestă în privința a ceea ce poate folosi efectiv o execuție autonomă:
- Un task offline nu oferă niciunul: cu sau fără ieșire din backend, un task fără acces
la rețea rămâne offline — aceeași logică ca la
web_search. - Un server care cere o credențială personală nesalvată de utilizator este filtrat încă de la ofertare, pentru că o execuție autonomă nu se poate opri ca să o ceară. Adăugați credențiala în Setări → Instrumente, iar următoarea execuție oferă serverul.
- Modul de acces la instrumente (numai administratori sau toți utilizatorii) și vizibilitatea per server se aplică exact ca în chat, iar legăturile unei persona cu serverele de instrumente restrâng ce servere vede agentul angajat sub ea.
- Când aprobările sunt active, instrumentele conectate pe care serverul le clasifică drept cu efect secundar se opresc pentru decizia dumneavoastră ca orice acțiune supravegheată; cele numai pentru citire rulează fără confirmare.
Delegare între agenți (@-mentions)
Agenții angajați își pot pasa munca. Tastați @ în compozitorul Work pentru a menționa alt
agent al dumneavoastră; agentul curent își vede în instrucțiuni lista colegilor (nume și linii
de stare) și deleagă cererile potrivite cu instrumentul message_agent. Delegarea este
coordonare prin mesaje, deliberat nu prin calculatoare comune: fiecare agent păstrează propriul
workspace și sandbox izolat, iar destinatarul nu vede conversația care a delegat — cererea
trebuie să își poarte propriul context.
Delegarea este asincronă. Instrumentul se întoarce imediat, agentul-țintă rulează în task-ul
lui (conversația lui arată cererea etichetată Delegated by expeditor), iar când termină —
finalizat, cere intervenție, eșuat sau anulat — răspunsul lui final este livrat înapoi în
conversația agentului care a delegat, ca mesaj etichetat Report from agentul respectiv.
Dacă cel care a delegat încă rulează, raportul ajunge la modelul lui în runda următoare; dacă
este inactiv, raportul pur și simplu așteaptă în conversație — un raport nu pornește niciodată
singur o execuție, deci doi agenți nu pot face ping-pong. Execuțiile delegate nu pot delega mai
departe, o țintă ocupată eșuează onest în loc să intre în queue, iar cu aprobările active
message_agent se oprește pentru revizuire ca orice acțiune cu efect secundar (regula
Always-allow se limitează la acel unic agent-țintă).
Aprobarea acțiunilor (Auto Review)
Acțiunile cu efect secundar se pot opri pentru decizia dumneavoastră înainte să ruleze. Când
aprobările sunt active pentru un task — politica Work setează Require approval for
side-effecting actions sau comutatorul Auto Review al agentului e pornit — execuția se
oprește înainte de run_command, computer_act, delete_file, move_file sau
message_agent și afișează în conversație un card de decizie: Allow once, Always allow
sau Deny.
- Allow once rulează exact acest apel și întreabă din nou data viitoare.
- Always allow rulează apelul și salvează o regulă pe task: pentru tot instrumentul la
acțiunile de fișiere și de calculator, limitată la programul comenzii (primul ei token) la
run_command— aprobarea luinpm run buildpreaprobă viitoare comenzinpm, nu tot shell-ul — și limitată la unicul agent-țintă lamessage_agent. Regulile sunt listate în secțiunea Auto Review din fila Agent și pot fi șterse acolo. - Deny refuză apelul. Modelul află că utilizatorul a respins acțiunea și nu trebuie să o reia ca atare; execuția continuă cu acest răspuns.
O aprobare în așteptare produce și o notificare (în aplicație și web push când e activat), pentru că execuția poate fi de minute bune în lucru nesupravegheat când ajunge la barieră. Dacă nimeni nu decide în cinci minute, cererea expiră, acțiunea nu se execută, iar execuția se încheie ca Needs input, cu handoff normal, în loc să își consume bugetul așteptând.
Aprobările controlează acțiunile, nu vizibilitatea: write_file și instrumentele numai pentru
citire rămân neblocate, iar fiecare decizie ajunge în jurnalul de audit de securitate.
Stare task
| UI | Backend | Culoare |
|---|---|---|
| Idle | idle | rgb(255, 255, 255) |
| Thinking | preparing sau running | rgb(48, 121, 255) |
| Complete | completed | rgb(76, 212, 117) |
| Needs input | needs_input sau cancelled | rgb(255, 204, 0) |
| Error | failed | rgb(255, 61, 129) |
Stop → Needs input cu fișiere păstrate. Epuizarea rounds/tools tot Needs input după handoff fără tools, niciodată Complete pentru lucru incomplet.
Run activ nu blochează conversația: mesajul intră imediat și ajunge la următorul round pentru steering. Stop rămâne disponibil.
Redimensionare
La xl, split draggable Conversation/Workspace: implicit 45 %, preferat 30–70 %, ratio
per user/browser, săgeți 2 %, Shift 10 %, Home/End min/max, Enter/dublu click reset.
Urmează direcția scrierii; în arabă Conversation dreapta, Workspace stânga. Pe mobil folosiți switcher.
Fișiere
Files vede copiii direcți /workspace, deschide strict UTF-8 și salvează în volume.
Bytes invalizi sunt refuzați. Editorul are syntax light/dark, Cmd/Ctrl+S,
Shift+Alt+F, conflict detection, drafts per task/path și avertismente.
Highlight se oprește peste 8.000 caractere/400 linii; formatting până la 100.000/4.000 pentru JS/TS/JSON/CSS/HTML/Markdown/YAML.
La schimbare de model, Files arată diff roșu/verde de la începutul turei, pliază
neschimbat, toggle diff/editor și +added −removed. Baseline este ultimul conținut văzut;
fișier deschis după tură nu are diff. Drafts sunt conveniență, nu backup, și se curăță la save/delete/session end.
Activitate
Activity arată tool calls/results, fișiere, output și erori. Metadata se extinde, output
rămâne LTR. Run activ deschide SSE autentificat cu snapshot, run_state,
reasoning_delta, assistant_delta, tool_call, tool_result, usage, skill_loaded,
error, done.
Reasoning depinde de provider; Libre arată numai ce returnează API și nu recuperează chain-of-thought. Text/tools pot streama independent. Output este limitat; truncarea nu dovedește lipsa altui output.
Git
Git oferă operații locale în /workspace: init main, status, ahead/behind, 20 commits,
diff limitat, stage până la 200 paths, commit cu identitatea admin/no-reply, branch local
și switch cu working tree curat.
Este local-only: fără clone/fetch/pull/push/remotes/comenzi arbitrare/token/SSH/PR. Acestea cer broker separat, ideal GitHub App limitat la repo/operație. Nu puneți credentiale de lungă durată în workspace, env sau config.
Reads merg idle/active. Writes sunt refuzate când model, terminal sau preview deține
containerul; branch switch cere tree curat. Comenzile UI sunt arrays fixe ca
1000:1000, fără shell input. Se dezactivează config system/global, prompts, hooks,
credential helpers, signing, submodules, external diff, textconv și network protocols.
Se refuză repo cu tree/Git dir în afara /workspace sau filtre executable.
Protejează API-ul Git, nu comenzile arbitrare din Terminal/run_command; sandboxul rămâne limita.
Skills worker incluse
Fiecare run primește ghid server-owned despre /workspace, root read-only, procese și
/tmp temporare, rețea, limite, preview. Învață modelul să inspecteze instrucțiuni,
manifest/locks/scripts/repo, să păstreze lucru neînrudit, să continue implementarea,
să verifice focalizat, să diagnosticheze și să pornească preview după verificare.
Ghidul există numai în context; nu se creează AGENTS.md sau control file și
instrucțiunile proiectului nu suprascriu securitatea.
Terminal
Terminal conectează shell interactiv la același sandbox ca 1000:1000 în /workspace,
fără privilegii suplimentare.
- Auth — Authorization se schimbă pe ticket scurt one-use bound la protocol/task,
doar ticket/ID în
/ws/work-terminal. Fiecare input reverifică cont/acces/ownership; revoke închide și eliberează lease. - Origin — cu
CORS_ORIGIN/BASE_URL, browser upgrade trebuie să corespundă. Clienții fără origin tot cer ticket; folosiți TLS/firewall/proxy. - Admission — terminal ia lease și contează în
WORK_MAX_ACTIVE_RUNTIMES_*. - Lifetime — ține containerul pornit.
- Concurrency —
WORK_TERMINAL_MAX_SESSIONS_PER_TASK, implicit 2. - Idle —
WORK_TERMINAL_IDLE_TIMEOUT_MS, implicit 15 minute. - Run activ — așteaptă sfârșitul turei.
Vorbește direct cu Docker Engine API pentru stream TTY. Folosește
WORK_DOCKER_SOCKET, altfel DOCKER_HOST (unix:// sau HTTP tcp:// proxy cu
Connection: Upgrade), altfel /var/run/docker.sock. ssh:// sau TLS tcp://
raportează indisponibil fără fallback. Kubernetes folosește exec WebSocket cu resize.
Sesiunile nu sunt înregistrate și comenzile nu apar în Activity.
Preview
Cu comandă goală, Libre:
- rulează
devdinpackage.jsonroot cu host/port; - servește
index.htmlroot cu server inclus; sau - aceeași regulă pentru o singură app nested.
Root are prioritate. Multiple/no entry returnează eroare acționabilă. Pentru alte
layouturi introduceți comandă înainte de Start preview. Începe în /workspace, de
exemplu cd apps/web && npm run dev -- --host 0.0.0.0 --port 4173, trebuie să asculte
0.0.0.0/WORK_PREVIEW_PORT, timeout 15 s.
Modelul folosește start_preview, singura cale de proces persistent; run_command curăță descendenții.
Ecran (Work Computer)
Vedeți demonstrația completă: rulare reală, needidată (30× apoi timp real), în care agentul navighează galerii NASA, alege fotografii și construiește/testează o galerie Three.js dintr-un singur prompt.
Un task cu Work Computer primește Screen: fereastră live către desktop virtual în același sandbox — window manager, dock și Chromium la 1280×800. Puteți urmări, prelua mouse/keyboard, asculta audio și preda prin demonstrație. Deschiderea pornește GUI on-demand și conectează viewer VNC-over-WebSocket.
Adminul activează cu un click: landing page arată cardul Work Computer cu Enable.
Construiește image-ul GUI pe daemonul propriu (prima dată câteva minute) și creează
policy gata, fără docker build manual. În spatele proxy filtrat, build endpoint este
refuzat; faceți pull pe host (ghcr.io/libre-webui/libre-work-computer, tag
libre-work-computer:latest) sau build din deploy/work-computer/. Enable apoi sare
buildul. Taskurile cer network access deoarece ecranul folosește port loopback ca preview.
Securitate: serverul VNC ascultă localhost cu două parole per sesiune — view-only pentru watchers și full-control numai holderului takeover lease — deci inputul altora este inert. WebSocket bridge este singura suprafață, publicată doar loopback. Fiecare viewer folosește ticket one-use bound la session/task, iar accesul Work este reverificat; revoke taie imediat. Până la patru viewers, iar watching contează activitate.
Watching și run nu concurează: deschiderea mid-run se atașează sandboxului runului, nu
blochează următorul și sesiunea supraviețuiește finalului, inclusiv team external worker.
Profilul browser persistă în /workspace/.browser-profile.
Control agent: computer_observe returnează screenshot complet, cursor, fereastră
activă, URL, focus page/browser, descriptor element și hash. Semantica vine din DevTools
loopback și poate lipsi în images vechi. computer_act execută batch până la 24 acțiuni
mouse/keyboard și returnează screenshot stabilizat.
Trei garduri: type/key pot declara focus și fail closed dacă nu corespunde, pentru
a nu scrie în omnibox. Batch se oprește la fereastră nouă, titlu sau focus schimbat,
fiindcă coordonatele sunt vechi. Poate declara outcome așteptat (title, URL, region),
verificat cu deadline adaptiv; "pending" nu înseamnă success. Ecranul se stabilizează prin polling.
Rezultatele au dovezi: click receipt pentru schimbare pixels, scroll_until spre text/
edge cu visibility și diff față de observația anterioară. subgoal pe o linie persistă
ca checkpoint și reapare în recovery prompts.
Agent loop detectează grounding stalls (trei acțiuni identice pe ecran neschimbat dau o singură recovery notice, repetarea încheie cerând input) și ambiguitate (expectations neverificate consecutive). Telemetria rounds, latency, screenshots, guards, verdicts se scrie pe tool records și se rezumă la final.
Screenshots ajung ca imagini reale prin Ollama, Anthropic, Gemini și OpenAI Chat/ Responses, deci preferați vision model. Dacă text-only respinge, run nu eșuează: screenshots se elimină, modelul folosește observații text și transcriptul explică degradarea. Fără vedere verificarea e slabă. Numai cele recente rămân în context, iar transcriptul persistent păstrează doar text, nu bytes.
Browserul are content blocking: uBlock Origin Lite pentru ads/trackers (pinned, checksum-verified, policy managed) și auto-dismiss cookie banners. Known ad scripts devin stubs locale inofensive. Agentul nu introduce credentiale și nu rezolvă CAPTCHA/2FA; raportează blocajul. Pentru tasks neîncrezute combinați GUI cu DNS filtrat.
Audio: ecranul este muted implicit; speaker streamă sunetul. PulseAudio joacă într-un
null sink, monitorul este PCM și servit prin al doilea WebSocket loopback autentificat,
cu același ticket/check/cap. Cere image din deploy/work-computer/ curent sau nou.
Takeover: Take over oferă mouse/keyboard pentru login/CAPTCHA și I'm done dă înapoi. O sesiune VNC are parolă full și view, generate per session, nelogate. Watchers primesc view, full numai lease holder. Lease TTL expiră în două minute, se reînnoiește cu UI deschis și nu poate fi furat.
Policy poate dezactiva prin Allow screen takeover. Taskurile ascund Take over/Teach,
endpointul refuză și request_takeover raportează imposibil; watching rămâne. Cât omul
controlează, computer_observe și computer_act sunt blocate, deci agentul nu luptă și
nu capturează textul. Agentul poate cere takeover cu banner/reason și aștepta handback.
Credentialele merg direct keyboard→page, niciodată model/transcript. Images vechi sunt view-only.
Teach: Teach a task înregistrează demonstrație reală cu indicator și acțiuni în coordonate. Fiecare click este ancorat de probe read-only la tag/id/label și URL, astfel pașii numesc ținta — "Click "button#submit (Place order)"" — iar coordonatele sunt hints.
Save construiește playbook determinist, fără model în buclă: tastele se grupează,
click/drag la 8 pixels, pauzele devin waits, iar textul de tip secret/credential (8+
caractere, trei clase) este redactat și înlocuit cu request_takeover.
Playbookul este procedură naturală cu targets ancorate, coordonate hints,
reinterpretare computer_observe, when-to-use, inputs, steps, verification, allowed
scope din hosturile vizitate (stop/ask înainte de ieșire; fără autoritate suplimentară),
approval boundaries și stop-and-ask la eșec. Se salvează skill taught- în Skills cu
versioning/edit/share.
Runs cu computer încarcă taught skills activate ale ownerului în system prompt și le
raportează. Replay este run normal potrivit procedurii. După run, chips oferă review
worked/failed ce adaugă linie datată în Track record (nou întâi, limitat, fiecare
versiune). Nu introduceți parole reale la predare; demonstrați până la login și folosiți
request_takeover la replay.
Furnizori, rutare și divulgarea datelor
Rute suportate
| Rută | Validare și comportament |
|---|---|
| Ollama local | Sănătos și modelul exact declară tools |
| Ollama Cloud | Rutare explicită; sufix cloud arată disclosure remote |
| Plugin completion/chat | Activ, model exact și credential admin curent |
| Plugin Anthropic | Adaptor Messages/tool-use Work |
| Plugin Gemini | Adaptor contents/function-calling Work |
| Alte pluginuri | Format OpenAI messages/tools/tool-choice |
Tipul providerului și plugin ID se stochează pe task și run. Numele singur nu alege ruta, iar un plugin cu același nume Ollama nu interceptează task existent.
Ce primește furnizorul
La fiecare round poate primi:
- system prompt Work, skills și limite runtime;
- până la 30 mesaje user/assistant, max 256 KB;
- definiții Work, istoricul tool calls și rezultate cu directoare, fișiere, search, output, erori.
Volumul nu se încarcă integral, dar orice conținut returnat de tool intră în conversație și ajunge la provider. Verificați retention, training, pricing și usage înainte de surse sensibile.
Credentialele rămân în backend și nu sunt montate în container. Criptarea credentialelor nu criptează întreg taskul: conversațiile și results sunt conținut obișnuit în bază, fișierele obișnuite în volume/PVC. Folosiți control host și criptare disc după threat model.
Informare furnizor remote
Pluginurile și numele Ollama cu :cloud sau -cloud sunt remote. Se afișează notice
dismissible despre data flow și multiple calls facturabile, cu preferință per utilizator.
Toate rutele folosesc WORK_MAX_AGENT_ROUNDS, implicit 48, fără clamp separat 12.
Bugetul tool calls este maximul dintre 128 și opt per round. La epuizare, modelul primește
un handoff final fără tools despre lucru, verificări, blocaje și pași. Runul devine
Needs input, nu raw exception sau Complete fals. Follow-up continuă același workspace.
Workspace în folder host (opt-in)
În Docker, /workspace este implicit volume per task, inaccesibil fișierelor reale.
Opțional se poate bind la folder host. Kubernetes refuză și folosește PVC.
WORK_HOST_WORKSPACES_ENABLED=true
WORK_HOST_WORKSPACE_ROOTS=/Users/you/Projects
WORK_HOST_WORKSPACE_ROOTS este listă : de rădăcini, implicit home server user. Când
este activ, apare Workspace folder opțional; gol păstrează volume izolat.
Calea trebuie absolută, existentă, director și după symlink în rădăcina permisă. Sunt
refuzate .ssh, .gnupg, .aws, .config, .kube, .docker, .claude,
.libre-webui, node_modules. Calea rezolvată se stochează și afișează.
Modelul citește și scrie fișiere reale, iar non-root/capabilities/limits nu mai stau între el și director. Țineți funcția oprită, rădăcinile înguste și preferați version control.
Persistență și ciclul runtime
| Stare | Stocare | Durată |
|---|---|---|
| Ownership, titlu, provider, status | Baza Libre | Până la ștergerea taskului/userului |
| Runs, errors, mesaje, tools | Baza Libre | Până la ștergerea taskului |
| Fișiere workspace | Volume Docker/PVC task | Supraviețuiesc anulării și restarturilor |
| Rootfs și temporare | Container/Pod task | Disposable |
| Proces preview | Sandbox activ | Efemer cât este sănătos |
| Draft editor | Browser session storage | Temporar |
Fiecare task primește UUID server-generated. Numele sunt derivate în backend, niciodată acceptate din browser. Resursele au labels managed/ownership; înainte de reuse/delete se verifică labelul și se refuză alt owner.
Sandboxurile sunt on-demand. File helpers opresc un sandbox altfel idle, comenzile îl opresc după final, iar preview sănătos îl poate menține. Workspace se remontează la restart/recreate.
Adminii definesc named runtime policies în fila User Management din Setări: runtime image, memory/ CPU/PID, workspace size Kubernetes, idle timeout, network default și switch-uri Work Computer (GUI + browser) și Allow screen takeover (și Teach, care înregistrează prin takeover). Taskul folosește configurația; câmpurile goale moștenesc global, ștergerea policy revine la global la următorul recreate. Policy schimbă numai resurse/capabilities, nu poate slăbi non-root, read-only rootfs, dropped caps, network isolation.
WORK_RUNTIME_IDLE_TIMEOUT_MS limitează grace preview: sweep oprește sandbox fără
comandă, terminal sau request preview pentru acei ms și eliberează slotul. Workspace
persistă și repornește la folosire. Default 0 păstrează preview până la stop explicit.
La startup, runs active devin failed și preview state se șterge. Driverul listează resurse managed printr-o interogare label: sandboxuri running cu task cunoscut sunt oprite fiindcă o comandă întreruptă poate continua; cele oprite rămân; orfanii fără row se elimină. Ownership vine din label, nu nume. O instanță trebuie să dețină namespace/ daemon; nu indicați două la aceleași resurse. Dacă cleanup nu poate fi dovedit, Work fail-closed, reîncearcă la 10 secunde și blochează mutații.
Comportamentul rețelei
Taskurile fără named policy pornesc cu rețea. Adminul poate defini policy cu network off, selectată la creare. Nu există switch independent per task; schimbarea cere recreate.
În Docker, taskurile cu rețea se conectează la bridge managed (libre-webui-work,
WORK_NETWORK_NAME) cu com.docker.network.bridge.enable_icc=false:
- sandboxurile nu se conectează între ele;
- nu ating containerele instalației pe default bridge, inclusiv DB/Ollama nepublicate.
Libre refuză o rețea existentă cu același nume fără label managed. În Kubernetes,
Podul are label și Helm instalează default-deny, ingress preview și internet egress
excluzând work.networkPolicy.blockedEgressCidrs. Funcționează numai cu CNI enforcement;
vezi Kubernetes.
Egress extern rămâne pentru packages, Git și API. Nu este firewall outbound. Codul poate atinge servicii host, LAN, internet și metadata infrastructură.
Hooks policy egress
WORK_RUNTIME_DNS(Docker) — adrese IPv4/IPv6 separate prin virgule, impuse cu--dns. Un resolver filtrat oferă allow/deny după nume. Valorile neadresă sunt refuzate, deci nu injectează flags.- Firewall host/upstream pe subnetul bridge managed.
WORK_NETWORK_NAMEspre rețea pre-creată cu opțiuni proprii; Libre verifică label managed și ICC disabled.
DNS nu blochează IP direct; garanția cere firewall host/cluster/upstream. Nu presupuneți că Work împiedică exfiltrarea. Dați acces numai utilizatorilor de încredere și folosiți named policy fără rețea pentru offline; nu există env global care schimbă default.
Accesul la rețea nu adaugă credentiale. Nu se montează SSH keys, cloud credentials,
browser profiles, home sau socket. Codul poate transmite ce se scrie în /workspace.
Traficul sandbox este separat de traficul modelului, trimis mereu de backend la ruta selectată.
Limita de securitate a sandboxului
Containerul Docker:
- rulează UID/GID
1000:1000, working dir/workspace, numai volume task; - rootfs read-only,
/tmplimitat, toate capabilities dropped,no-new-privileges, non-privileged init; - CPU, memory, process, command-time și output limits;
- swap fixat (
--memory-swapegal--memory); - rețea managed fără ICC sau fără rețea;
- publică numai preview port pe loopback alocat.
Totul este reverificat cu docker inspect și hashuit în label ai.libre-webui.policy.
Policy veche după upgrade duce la destroy/recreate.
Kubernetes aplică echivalent: non-root UID/GID, read-only root, RuntimeDefault, fără
escalation/capabilities, storage/limits, fără ServiceAccount token și PVC task. Verifică
labels și fingerprint înainte de reuse/delete.
Validarea căilor refuză absolute, traversal, backslashes, NUL și prea lungi. Helpers rezolvă real paths și symlink escapes; writes folosesc temp și atomic rename.
Controalele reduc expunerea, nu fac VM sau malware lab. Containerele împart kernelul și vulnerabilități runtime/image/dependency/kernel pot trece. Docker volumes nu au quota independent; proiectul poate umple storage, deci monitorizați și aplicați limite host. Kubernetes cere PVC size, enforcement depinde de provisioner.
Checklist hardening Docker în producție
Kubernetes trebuie să valideze RBAC namespace, Pod security, StorageClass și CNI NetworkPolicy conform Kubernetes. App poate seta flags și valida căi, nu poate impune firewall host, quota driver sau privilegiul daemonului.
1. Izolați controlul Docker
Containerul principal are nevoie de control daemon pentru Work; socketul este credential control-plane, iar compromiterea app poate compromite hostul.
docker-compose.socket-proxy.yml ține socketul în afara Libre. Proxy internă deține
/var/run/docker.sock și permite containers, images, volumes, networks, exec, info,
refuzând swarm, secrets, configs, build, commit, system. Libre folosește
DOCKER_HOST=tcp://docker-socket-proxy:2375 fără mount/grup; CLI, Terminal și diagnostics
urmează endpointul. Proxy reduce suprafața, nu blast radius: create container permite
bind mount host.
Mai puternic: host VM dedicat fără workloaduri; și mai puternic daemon rootless dedicat sau runtime host separat. Verificați ownership, preview, cleanup și terminal. Socketul rootful read-only nu face API read-only.
2. Blocați accesul sandbox la management host
ICC off împiedică sandbox-sandbox, nu servicii pe host. Inspectați bridge/subnet:
docker network inspect libre-webui-work \
--format 'id={{.Id}} subnets={{range .IPAM.Config}}{{.Subnet}} {{end}}'
ss -lntup
Folosiți firewall persistent pentru trafic din bridge către SSH, Docker API, DB și
porturi admin. Testați din container disposable și downloads permise, apoi persistați.
DOCKER-USER controlează forward; destinația host poate cere regulă INPUT pe interfață.
3. Limitați destinațiile de ieșire
Blocați cloud metadata, infrastructura privată și LAN-urile clienților din subnetul Work,
exceptând nevoile explicite. Combinați resolver filtrat prin WORK_RUNTIME_DNS cu
firewall host/upstream. DNS singur se ocolește prin IP literal, iar proxy HTTP singur nu
oprește comenzi cu conexiuni directe; aplicați politica în afara containerului.
Păstrați named policies separate: offline, numai package registry și egress deschis. Policy decide atașarea rețelei, firewall/proxy externe decid destinațiile.
4. Impuneți cote reale de stocare
Limitele CPU/memory/swap/PID nu limitează volume. Pentru mai mulți clienți folosiți
backend cu quota per workspace: XFS project quota, logical volumes sau driver volume/PVC
cu limită. Driverul Docker local pe ext4 nu primește cotă doar prin documentarea mărimii.
Monitorizați volumele ai.libre-webui.managed=true și Docker data root, alertați înainte
de full și testați eșecul. Counter UI sau du avertizează, nu impun, deoarece containerul
poate consuma discul între verificări.
5. Verificați politica deployed
După schimbare image/daemon, creați task disposable și verificați cu docker inspect:
UID non-root, root read-only, capabilities dropped, no-new-privileges, memory/swap/
CPU/PID, numai volume task și rețeaua așteptată. Verificați mounts ale containerului
principal și ingress numai prin proxy/tunnel autentificat, nu port Docker/preview publicat accidental.
Securitatea și accesibilitatea previewului
Docker publică preview pe port dinamic loopback; Kubernetes țintește Pod IP din cluster.
Modelul/browserul nu aleg upstream. Libre semnează capability URL pentru task/endpoint,
verifică preview la fiecare cerere și proxy-ează HTTP/WebSocket prin /api/work/previews.
Stop/restart revocă URL vechi.
Răspunsurile elimină credentiale Libre și cookies upstream. HTML are iframe sandbox și CSP care permit scripts, forms, modals, downloads fără same-origin. CSP protejează și fila separată. Codul rămâne neîncrezut și poate folosi egress pentru date din workspace sau browser input. Tratați URL preview ca secret scurt și nu îl partajați.
Browserul încarcă proxy pe originul public Libre, deci remote și HTTPS funcționează fără
porturi/POD IP și fără mixed content. Reverse proxy trebuie WebSocket upgrade pentru
/api/work/previews/; Nginx furnizat face asta.
Aplicația principală permite ca frame sources doar originul propriu și Cloudflare Turnstile. Preview ocolește politica Helmet pentru streaming și CSP mai îngust. Cross-origin embedder rămâne off deoarece dev servers nu emit headere compatibile.
Matrice deployment
Disponibilitatea urmează mașina/procesul backend, nu doar browserul.
| Deployment | Runs și fișiere | Preview |
|---|---|---|
npx libre-webui local | Cu Docker instalat, pornit și apelabil | Proxy semnat origin aplicație |
| Source local | Aceleași cerințe Docker/provider | API dev port 3001 |
| Electron | Condiționat; folosește backend extern, fără runtime propriu | Proxy acelui backend |
| Bare metal/VM remote | Cu Docker pe host | Reverse proxy HTTP/WebSocket |
| Docker Compose standard | Suportat implicit pe Docker Desktop: image are CLI, Compose montează socketul, iar porturile Work trec prin host.docker.internal. Docker Engine nativ mai cere un WORK_PREVIEW_BIND nepublic accesibil | Același origin public |
| Kubernetes/Helm curent | Cu --set work.enabled=true: Pods/PVC, RBAC scoped, default-deny, fără socket; vezi Kubernetes | Proxy semnat direct la Pod IP |
Work când Libre WebUI rulează în Docker
Toate fișierele Compose activează Work: image are Docker CLI și montează
/var/run/docker.sock. Docker Desktop funcționează cu rutarea implicită livrată;
Docker Engine nativ mai cere WORK_PREVIEW_BIND setat pe o interfață de host
nepublică, accesibilă din containerele frați, așa cum se descrie mai jos.
Task containers sunt siblings ale containerului Libre, vizibile în docker ps și
curățate de același lifecycle. Socketul dă control root-equivalent hostului; Work nu
funcționează fără el, deci consecința este explicită: fiecare administrator Libre este
efectiv administrator Docker host. Operatorul deține securitatea, rețeaua, lifecycle,
backup și acces. Ștergeți linia socket pentru a opri Work; nimic altceva nu depinde.
Pentru Work fără socket în web app, folosiți docker-compose.socket-proxy.yml; proxy
internă deține socketul, permite numai API-urile Work și Libre o atinge prin DOCKER_HOST.
Vezi Izolați controlul Docker.
Trei condiții, iar panelul numește eșecul:
- Docker CLI există în image. Custom cere
docker-clisauWORK_DOCKER_COMMAND. Altfel:The "docker" CLI is not installed…. - Socket montat. Altfel:
No Docker daemon is reachable…. - User backend în grupul socket. Image rulează
nodejsuid 1001, socket de obiceiroot/docker, Compose dăgroup_add: ['${DOCKER_GID:-0}']. Docker Desktop se potrivește, Linux cere grup propriu. Altfel:The Docker socket is mounted but the Libre WebUI user cannot open it….
# Read the socket's group as seen INSIDE a container. A macOS host reports a
# different value, because Docker Desktop proxies the socket through a VM.
echo "DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
alpine stat -c '%g' /var/run/docker.sock)" >> .env
docker compose up -d --force-recreate
Preview ports rămân loopback. Libre le expune prin proxy semnat cu HTTP/WebSocket, funcționând prin HTTPS/tunnel fără port efemer public. Sandbox policy restrictiv și stop/restart revocă URL.
Când backend este Docker, publicarea și conectarea pot folosi adrese diferite. Păstrați
WORK_PREVIEW_BIND=127.0.0.1 și setați WORK_DOCKER_PUBLISHED_HOST la adresa host
accesibilă din container (host.docker.internal pe Desktop). Profilurile Compose livrate
setează ambele valori și mapează numele de host. Pe Linux nativ trebuie să suprascrieți
WORK_PREVIEW_BIND cu gateway-ul punții Docker (sau altă interfață de host nepublică,
explicit accesibilă); simplul alias nu face loopback accesibil. Nu legați niciodată
aceste porturi efemere brute la 0.0.0.0.
Concurența: WORK_MAX_ACTIVE_RUNTIMES_PER_USER implicit 2, global 3. Capabilities
raportează limite și occupancy. Măriți numai cu resurse.
Pentru Kubernetes instalați work.enabled=true, nu socket node; chartul creează RBAC,
namespace, policies și Pod/PVC din Kubernetes.
Configurație runtime
| Variabilă | Implicit | Scop |
|---|---|---|
WORK_RUNTIME_BACKEND | docker | Driver docker/kubernetes |
WORK_RUNTIME_IMAGE | node:22.22-bookworm@sha256:2d178f2785b96dfbf62a416ca2e40f50e30150b4ff3320d706f0d96e90600eb3 | Image sandbox |
WORK_DOCKER_COMMAND | docker | CLI Docker |
WORK_COMMAND_TIMEOUT_MS | 120000 | Timeout comandă |
WORK_MAX_OUTPUT_CHARS | 50000 | Output max |
WORK_MAX_AGENT_ROUNDS | 48 | Buget rounds per run |
WORK_MEMORY_LIMIT | 2g | Memorie container |
WORK_CPU_LIMIT | 2 | CPU container |
WORK_PIDS_LIMIT | 256 | Procese container |
WORK_PREVIEW_PORT | 4173 | Port intern preview |
WORK_PREVIEW_BIND | 127.0.0.1 | Interfață host preview |
WORK_DOCKER_PUBLISHED_HOST | same as WORK_PREVIEW_BIND | Host apelat de backend |
WORK_COMPUTER_SCREEN_PORT | 6080 | WebSocket screen intern |
WORK_COMPUTER_AUDIO_PORT | 6081 | WebSocket audio intern |
WORK_RUN_LEASE_WAIT_MS | 60000 | Așteptare lease |
WORK_MAX_ACTIVE_RUNTIMES_GLOBAL | 3 | Taskuri container simultane globale |
WORK_MAX_ACTIVE_RUNTIMES_PER_USER | 2 | Simultane per admin |
WORK_MAX_TASKS_GLOBAL | 500 | Taskuri persistente globale |
WORK_MAX_TASKS_PER_USER | 100 | Taskuri per admin |
WORK_NETWORK_NAME | libre-webui-work | Bridge managed |
WORK_RUNTIME_DNS | unset | Resolvere forțate |
WORK_DOCKER_SOCKET | DOCKER_HOST if unix:// or tcp://, else /var/run/docker.sock | Endpoint terminal Docker |
WORK_TERMINAL_MAX_SESSIONS_PER_TASK | 2 | Terminale simultane |
WORK_TERMINAL_IDLE_TIMEOUT_MS | 900000 | Timeout terminal |
WORK_RUNTIME_IDLE_TIMEOUT_MS | 0 (disabled) | Stop sandbox după inactivitate |
WORK_K8S_NAMESPACE | libre-webui-work | Namespace Pod/PVC |
WORK_K8S_STORAGE_CLASS | cluster default | StorageClass PVC |
WORK_K8S_WORKSPACE_SIZE | 5Gi | Mărime PVC per task |
WORK_K8S_POD_READY_TIMEOUT_MS | 900000 | Așteptare ready Pod |
WORK_K8S_POD_GONE_TIMEOUT_MS | 60000 | Așteptare ștergere Pod |
În producție fixați versiune/digest. Tag mutabil poate schimba tools și security boundary.
Un endpoint tcp:// cu DOCKER_TLS_VERIFY activat nu este folosit de clientul terminalului.
Run, preview, file helpers, commands și recreate împart accounting în proces. Operație nested pe task deja numărat nu adaugă task. Peste limite returnează HTTP 429.
Limite fixe protocol și UI
| Element | Limită |
|---|---|
| Mesaj task/run nou | 65.536 caractere și bytes UTF-8 |
| ID model la creare/update | 500 caractere și bytes UTF-8 |
| ID provider plugin | 200 caractere |
| Runs active per task | 1 |
| Text comandă | 20.000 caractere |
| Timeout tool | 1–600 secunde |
| Preview ready | 15 secunde |
| Citire/scriere fișier | 2.000.000 bytes UTF-8 |
| Listare director | Primele 1.000 |
| Pagină mesaje | 200 mesaje, 1.000.000 bytes |
| Mesaj persistent | 100 KB |
| Context model | Ultimele 30, max 256 KB |
| Output tool persistent | ~20.000 caractere + marker |
| Highlight live | 8.000 caractere, 400 linii |
| Formatting browser | 100.000 caractere, 4.000 linii |
| Git status/diff | 2.000.000 / 600.000 caractere |
| Git history/stage/message | 20 commits / 200 paths / 4.000 caractere |
| Agent loop | 48 rounds implicit prin WORK_MAX_AGENT_ROUNDS |
| Buget tool calls | max(128, configured rounds × 8) calls |
API-ul de fișiere este UTF-8 text, nu binary; peste 2 MB nu se deschide.
Rezumat API
Toate endpointurile sunt sub /api/work și cer autentificare plus acces Work curent.
Implicit admin-only; admin poate deschide operațiile obișnuite. Host-folder și policy
rămân admin-only.
| Metodă | Path | Scop |
|---|---|---|
GET | /capabilities | Disponibilitate runtime/provider și limite |
GET | /tasks | Lista taskurilor utilizatorului |
POST | /tasks | Creează task și primul run async |
GET | /tasks/:id | Stare și mesaje recente |
GET | /tasks/:id/messages | Pagini mesaje vechi |
PATCH | /tasks/:id | Redenumire/rută model |
DELETE | /tasks/:id | Șterge task și workspace |
POST | /tasks/:id/runs | Run următor |
POST | /tasks/:id/messages | Mesaj în timpul runului |
GET | /tasks/:taskId/runs/:runId/events | Stream SSE |
POST | /tasks/:id/cancel | Anulează run activ |
GET | /tasks/:id/approvals | Aprobări în așteptare + starea Auto Review |
PUT | /tasks/:id/approvals | Comută aprobările per task |
POST | /tasks/:id/approvals/:approvalId | Decide o aprobare (o dată/mereu, refuz) |
DELETE | /tasks/:id/approval-rules/:ruleId | Șterge o regulă Always-allow |
GET | /computer/setup | Stare setup Work Computer (admin) |
POST | /computer/setup | Build GUI și policy (admin) |
POST | /tasks/:id/computer/start | Pornește Work Computer |
GET | /tasks/:id/computer/control | Cine controlează/request takeover |
POST | /tasks/:id/computer/control | Take over/renew |
DELETE | /tasks/:id/computer/control | Returnează ecranul agentului |
POST | /tasks/:id/computer/teach | Salvează demonstrația ca skill |
POST | /tasks/:id/computer/anchor | Rezolvă element click |
POST | /computer/skills/:slug/trace | Adaugă worked/failed la skill |
GET | /tasks/:id/files | Listează director |
GET | /tasks/:id/file | Citește text |
PUT | /tasks/:id/file | Salvează text |
GET | /tasks/:id/git | Git status/history |
GET | /tasks/:id/git/diff | Diff limitat |
POST | /tasks/:id/git/init | Inițializează Git |
POST | /tasks/:id/git/stage | Stage paths |
POST | /tasks/:id/git/commit | Commit |
POST | /tasks/:id/git/branches | Creează branch |
POST | /tasks/:id/git/switch | Switch branch curat |
POST | /tasks/:id/preview/start | Pornește preview |
POST | /tasks/:id/preview/stop | Oprește preview |
Task ID se verifică față de owner. Status, rol și policy se citesc din bază la fiecare cerere, deci revocarea se aplică chiar cu JWT vechi.
Schema de update păstrează intern networkEnabled, dar UI nu îl expune. Selectați named
runtime policy la creare; nu folosiți câmpul brut ca API persistent.
Ștergere, schimbări de cont și backup
Ștergerea taskului
Este deliberat distructivă:
- Taskul devine retiring, fără mutații noi.
- Run activ se anulează și sandbox se oprește.
- Se validează labels ownership.
- Container/Pod și volume/PVC se șterg.
- Rândul bazei se șterge cu runs/messages cascade.
- Drafts browser se curăță după succes API.
Dacă runtime cleanup eșuează, rândul se păstrează și se returnează eroare pentru repair/ retry. Nu se șterg metadata lăsând sandbox neînregistrat. Stop run/preview păstrează volume și conversație.
Retrogradarea adminului și ștergerea utilizatorului
La demotion, rolul se persistă înainte de cleanup. Orice cerere verifică rol/acces. Backend suspendă taskurile, încearcă abort/stop. Dacă cleanup eșuează, accesul rămâne revocat și update raportează eroarea pentru retry.
Ștergerea altui utilizator elimină întâi toate resursele Work. Dacă runtime extern eșuează, user row se păstrează pentru ownership și retry sigur.
Backup complet al taskului
Necesită:
- baza Libre cu ownership, nume resurse, provider, runs, mesaje și activity; și
- fiecare volume/PVC cu label
ai.libre-webui.managed=true, conținând fișiere.
Containerele și preview nu se salvează. Pentru consistență opriți activitatea și backend,
apoi snapshot volume/PVC. Restaurați baza și workspace-urile potrivite împreună, sub
numele exacte și labels ai.libre-webui.task=<task UUID> și
ai.libre-webui.managed=true. Copierea fișierelor nu păstrează labels. Numai baza
înseamnă fișiere lipsă; numai storage pierde ownership/nume. Cu credentiale criptate,
urmați ghidul principal pentru data și key.
Localizare și RTL arab
Work este tradus în toate cele 25 locale: English, Arabic, Bengali, Czech, Danish, German, Spanish, French, Hindi, Indonesian, Icelandic, Italian, Japanese, Korean, Malay, Dutch, Polish, Portuguese, Russian, Swedish, Thai, Turkish, Ukrainian, Vietnamese și Chinese.
Arabic aplică lang="ar" și dir="rtl" înainte React. Sidebar dreapta, Conversation
dreapta, Workspace stânga, icons oglindite, tabs RTL și resize vizual RTL.
Conținut tehnic rămâne LTR: code/highlighting, paths, model IDs, commands/logs, tool output/metadata și code blocks. Nume task, prompts, errors, filenames și preview commands folosesc direcție automată.
Depanare
Runtime unavailable cu npx
npx libre-webui rulează backend pe host, nu instalează Docker. Rulați docker info ca
același OS user. Dacă lipsește sau nu ajunge daemon, instalați/porniți/reparați permisiuni
și reîncărcați Work. Verificați și Ollama sănătos sau plugin activ cu model/credential admin.
Runtime unavailable în Docker sau Kubernetes
Compose standard nu ar trebui: image are CLI și socket. Panelul numește CLI lipsă,
mount absent sau grup greșit; pentru ultimul setați DOCKER_GID și recreate. Vezi
Work când Libre rulează în Docker.
În Kubernetes activați --set work.enabled=true. Libre raportează kubernetes, probează
API și rulează Pods/PVC. Nu montați node socket; vezi Kubernetes.
Niciun model compatibil Work
Ollama trebuie să declare tools. Pentru plugin verificați type completion/chat, activ,
model exact în map, API key admin și tool calling. Work nu face fallback provider.
Package install sau Git remote eșuează
Policy selectată trebuie să permită rețea; nu există toggle per task. Inspectați DNS, proxy, firewall/NetworkPolicy, registry, certificat, runtime și upstream și comanda în image. Fila Git este local-only. Pentru remote folosiți Terminal/model numai dacă policy permite și nu puneți token lung în workspace.
Run se oprește la limita agentului
S-a epuizat round sau tool budget. Work cere handoff final, rămâne Needs input și nu
pretinde completion. Porniți follow-up în același workspace sau măriți deliberat
WORK_MAX_AGENT_ROUNDS dacă resursele/costurile permit.
HTTP 429 la pornire
S-a atins limita runtime/task. Așteptați stop, ștergeți tasks vechi sau măriți WORK_MAX_* pe host suficient.
Preview nu devine ready
Comanda trebuie să rămână, bind 0.0.0.0, asculte WORK_PREVIEW_PORT în 15 secunde.
Cu gol se detectează package.json dev sau index.html, inclusiv nested. La multiple/
fără entry introduceți command explicit; pornește /workspace, folosiți
cd <app-directory> && ....
Preview merge pe server, nu în browser remote
Folosiți build cu proxy semnat și restart preview pentru URL vechi. Dacă pagina merge,
hot reload nu, proxy/tunnel trebuie WebSocket upgrade la /api/work/previews/. Portul
Docker rămâne loopback, fără firewall public.
Fișierele rămân, preview s-a oprit
Normal după cancel, restart, stop sau readiness failed. Preview este efemer, volume persistent. Redeschideți și porniți.
Fișierul nu se deschide/salvează
API acceptă UTF-8 până la 2 MB. La conflict reîncărcați înainte de editare. Highlight devine text simplu peste 8.000/400; formatting separat 100.000/4.000 și numai familii suportate.
Work recuperează sandboxes
Startup/teardown nu a dovedit stop. Work fail-closed și retry 10 secunde. Reparați daemon/ Kubernetes și logs. Nu ștergeți DB rows cât resursele labeled trebuie reconciliate.
Ștergerea taskului eșuează
Runtime trebuie accesibil. Resursă cu nume conflictual fără label ai.libre-webui.task
este refuzată, nu ștearsă. Rezolvați ownership și reîncercați.
Rezumat securitate
- Work implicit admins-only; deschiderea tuturor face fiecare cont operator sandbox. Host-folder rămâne admin-only.
- Backend controlează daemonul Docker sau namespace Kubernetes.
- Containerele reduc expunerea, nu sunt VM.
- Fără named offline policy există egress; destinațiile sunt responsabilitatea operatorului.
- Volumele Work nu au quota independentă.
- Git este local-only și nu montează credentiale remote.
- Firewall host, izolare daemon, restricții egress și quota rămân controale operator.
- Provider remote primește tool results și poate face multe calls.
- Preview ports rămân loopback, prin URL semnat revocabil.
- Compose oferă Docker runtime; Kubernetes cu
work.enabled=truePod/PVC nativ. - Backup complet cere baza și volume Work.