25 KiB
PRD — Security hardening per Docker personale e server multiutente
Ripresa del lavoro e limiti di autorizzazione
Questo PRD resta una bozza, non una specifica di implementazione approvata. Il precedente prompt di ripresa è stato consolidato qui il 15 settembre 2026. Riconfermare i rilievi SEC-01–SEC-12 contro codice e dipendenze correnti, separando fatti, ipotesi, rischi del profilo locale/server e problemi già risolti. Le vecchie survey non provano lo stato del server. Usare inizialmente controlli in sola lettura e dati sintetici; accesso a server, IdP, DWH o provider e relative mutazioni richiedono target e operazioni concordati.
Prima di implementare, il proprietario deve confermare profili di fiducia, isolamento del runtime Pi, trattamento dei valori sensibili, revoca, retention, limiti di risorse, priorità e criteri misurabili. I modelli visibili sul server sono un problema separato. Registrare le decisioni in questo PRD; pubblicare spec e ticket Gitea soltanto dopo la conferma del perimetro e della granularità. La bonifica documentale non autorizza il codice di sicurezza, né il rollout di tutti i punti SEC.
L'implementazione futura richiede un worktree dedicato, test positivi/negativi ai confini concordati, typecheck e revisione contro standard e specifica. Conservare gate manuali, evidenze e rollback; un ticket completato non chiude automaticamente il PRD. Non copiare segreti o dati operativi nei worktree. Usare le skill effettivamente disponibili per chiarimento, diagnosi e revisione, senza assumere che i vecchi nomi dei comandi esistano.
Stato: bozza da validare con grill-with-docs; implementazione rinviata.
Data: 8 settembre 2026.
Owner delle decisioni: il maintainer di ThothII.
Ripresa: seguire la sezione «Ripresa del lavoro e limiti di autorizzazione» sopra.
Questo documento conserva la survey di sicurezza discussa con il maintainer e propone requisiti, priorità e criteri di accettazione. Non è una spec approvata, un penetration test, una certificazione o un'autorizzazione a intervenire sui deploy. Nessun ticket, worktree o intervento applicativo è stato avviato per questo PRD. Non è prevista un'esecuzione automatica alla scadenza di una data.
La survey aveva come riferimento HEAD 50c546e42d03281082af3679b8b8d7ce0d01aefa; alla
registrazione di questo documento HEAD è 818563c4085c9ebce69dca2cbc15ed71fe13f381.
Sono riferimenti per confrontare le revisioni, non attestazioni di un worktree originariamente
pulito. I rilievi derivano da lettura del codice, controlli locali mirati e audit delle dipendenze:
non è stata verificata la configurazione effettiva del server remoto. Alla ripresa ogni rilievo
deve essere riconfermato, chiuso con evidenza oppure riformulato rispetto al codice corrente.
Problema
ThothII deve avere un perimetro di sicurezza comprensibile e verificabile sia come applicazione Docker su un Mac o PC personale, sia come installazione server condivisa con autenticazione built-in oppure OIDC. Le protezioni esistenti non bastano, da sole, a dimostrare isolamento fra utenti, contenimento dell'agente e controllo delle informazioni inviate ai modelli.
In particolare, autenticare un utente non equivale ad autorizzarlo su una sessione o sui dati di un workspace; un gate del workflow non equivale a una sandbox; cifrare un vault non protegge dal furto congiunto del vault e della sua chiave.
Risultato desiderato
L'operatore sceglie un profilo supportato, riceve una diagnosi chiara delle configurazioni incompatibili e può verificare i controlli con prove ripetibili. L'utente accede soltanto alle risorse consentite. Credenziali e dati sorgente attraversano esclusivamente i confini approvati. I rischi residui sono espliciti e accettati dal maintainer, non dedotti dal passaggio dei test.
Profili da confermare
| Profilo | Confine e aspettativa proposta | Decisione ancora necessaria |
|---|---|---|
| Docker personale, singolo utente | Host fidato; interfaccia pubblicata su loopback; servizi interni non pubblici | Eventuale modalità senza login, accesso LAN e deroghe TLS ammesse |
| Server multiutente, built-in | HTTPS, account distinti, autorizzazione server-side e sessioni separabili | Risorse condivise, ruoli, recupero account e requisiti MFA |
| Server multiutente, OIDC | Stesse garanzie applicative; IdP come fonte di identità e attributi concordati | Mapping dei gruppi, scadenze, revoca e comportamento con IdP indisponibile |
Il luogo del deploy, la modalità di autenticazione e il backend di persistenza sono assi distinti.
In particolare, “Docker in locale” non significa necessariamente modalità di autenticazione
local, né richiede necessariamente persistenza filesystem. “Multiutente” non implica una
piattaforma SaaS multi-tenant: va deciso se gli utenti condividono gli stessi diritti sui dati.
Confini di fiducia
- Browser e richieste HTTP rispetto a reverse proxy, backend e identità autenticata.
- Utente A rispetto a sessioni, stream, artefatti e risorse dell'utente B.
- Processo Pi e contenuti non fidati rispetto a filesystem, credenziali e altri processi.
- ThothII rispetto a DWH, IdP, provider LLM ed endpoint embedding.
- Dati operativi rispetto a log, tracce Pi, indici, esportazioni e backup.
- Immagini e dipendenze distribuite rispetto al runtime installato.
Considerare almeno: richieste non autenticate, utente autenticato che tenta accessi non consentiti, contenuti DWH/documentali che inducono l'agente ad azioni improprie, segreti esposti accidentalmente e richieste che consumano risorse eccessive. La compromissione dell'amministratore dell'host non viene considerata risolvibile dal solo hardening applicativo; va esplicitato cosa resta esposto.
User stories
- Come operatore personale, voglio avviare Docker senza pubblicare involontariamente il servizio sulla rete.
- Come operatore server, voglio che combinazioni di autenticazione, esposizione e storage non sicure siano rifiutate con un rimedio leggibile.
- Come utente, voglio che conoscere l'ID di una sessione altrui non mi permetta di leggerla o modificarla.
- Come amministratore, voglio definire quali workspace e dati sono condivisi e quali richiedono autorizzazioni distinte.
- Come utente, voglio che login built-in e OIDC producano le stesse garanzie di autorizzazione applicativa.
- Come amministratore, voglio che logout, revoca e rimozione dei diritti abbiano tempi di efficacia dichiarati, inclusi gli stream aperti.
- Come responsabile dei dati, voglio che i valori sensibili non raggiungano un destinatario non autorizzato attraverso il grounding o la generazione.
- Come operatore, voglio verificare identità e cifratura del DWH, ricevendo un errore se la verifica richiesta fallisce.
- Come operatore, voglio che Pi disponga soltanto delle risorse necessarie al lavoro approvato.
- Come utente, voglio continuare a usare i gate umani e il resume senza perdere le protezioni di isolamento.
- Come responsabile dei dati, voglio sapere quali contenuti sono persistiti e per quanto tempo, anche fuori dagli artefatti di workflow.
- Come operatore, voglio diagnosticare errori senza leggere API key, password, token o campioni sensibili nei log.
- Come utente di un server condiviso, voglio che una richiesta costosa di un altro utente non esaurisca tutte le risorse disponibili.
- Come operatore dietro proxy, voglio limiti e controlli HTTP che usino correttamente l'origine delle richieste.
- Come maintainer, voglio aggiornamenti delle dipendenze verificabili e distribuzioni riproducibili.
- Come operatore, voglio backup ripristinabili con protezioni e limiti della cifratura espliciti.
- Come maintainer, voglio test negativi che dimostrino il rifiuto degli abusi, oltre ai percorsi leciti.
- Come operatore, voglio istruzioni di adozione e rollback per ogni cambiamento che coinvolge dati o configurazioni esistenti.
Registro dei rilievi della survey
Le priorità sono proposte, condizionate al profilo e all'esposizione. P0 indica un candidato bloccante per il rilascio del profilo interessato, P1 il successivo hardening e P2 il consolidamento. Non sono punteggi CVSS né affermazioni di sfruttabilità già dimostrata.
| ID | Evidenza o limite osservato nella survey | Rischio da verificare | Priorità proposta |
|---|---|---|---|
| SEC-01 | Senza session storage PostgreSQL il resolver usa il principal locale e il repository filesystem usa una radice condivisa | Attribuzione e separazione delle sessioni in combinazioni multiutente non supportate | P0 server; verificare prima i vincoli di configurazione già presenti |
| SEC-02 | Pi è un processo figlio del core; il gate dichiara di non essere una sandbox | Accesso a risorse o credenziali oltre il compito, anche per effetto di contenuti non fidati | P0 se si promette isolamento fra utenti non fidati; P1 personale |
| SEC-03 | Nel percorso DWH diretto era emersa una discontinuità fra configurazione TLS resa dal deployment e configurazione consumata dal connettore | TLS richiesto ma non applicato o verificato come atteso | P0 per connessioni che richiedono TLS; riconfermare per ogni driver |
| SEC-04 | Il grounding LSH restituisce valori reali; l'applicazione del Sensitive Data Flag a questo percorso è un follow-up esplicitamente rinviato | Valori sensibili nel contesto di un modello non autorizzato | P0 se quel percorso usa dati sensibili e un destinatario non autorizzato |
| SEC-05 | Pi ha una propria directory di sessione; la survey non ha trovato l'opzione che disabilita la persistenza nel lancio esaminato | Tracce aggiuntive rispetto agli artefatti dichiarati, con retention non verificata | P1; presenza e contenuto effettivo delle tracce da verificare |
| SEC-06 | Gruppi OIDC fotografati al login; autenticazione SSE all'apertura, senza evidenza di chiusura alla revoca | Permessi o stream utilizzabili oltre il tempo di revoca atteso | P1 server; elevare se il requisito richiede revoca immediata |
| SEC-07 | La permission di uso delle sessioni consente l'accesso all'elenco dei workspace senza una ACL per workspace osservata | Accesso ai dati più ampio del previsto se i diritti differiscono fra utenti | P0 con diritti differenziati; scelta esplicita altrimenti |
| SEC-08 | Un LIMIT già presente può superare il limite applicativo; fetch completo prima del taglio del risultato | Consumo eccessivo di memoria, DWH, processi e budget modello | P1, con particolare rilievo multiutente |
| SEC-09 | Rate limit basato sull'IP della richiesta; configurazione proxy fidati e hardening degli header da completare/verificare | Contatori condivisi impropriamente, fiducia errata negli header o difese browser incomplete | P1 server |
| SEC-10 | Audit storico con advisory nel runtime Pi; dipendenze Python runtime non interamente vincolate da un lock nella build esaminata | Vulnerabilità dipendenti dalla versione e build non riproducibili | P1; nuova scansione e verifica di raggiungibilità obbligatorie |
| SEC-11 | Core non-root, ma senza tutte le restrizioni osservate nel servizio di manutenzione | Impatto maggiore di un processo compromesso | P1 server, P2 personale salvo rischio specifico |
| SEC-12 | Vault cifrato con chiave locale adiacente; backup esaminato non cifrato come archivio | Copia congiunta di chiave e dati; esportazioni o backup troppo accessibili | P1 se esportati fuori dall'host, altrimenti priorità da concordare |
La survey aveva anche rilevato controlli da preservare: hashing Argon2id, cookie di sessione opachi con HttpOnly/SameSite, controlli CSRF/origin, OIDC con PKCE e nonce, revoca applicativa, RLS PostgreSQL, query read-only con timeout, container non-root e assenza di mount del socket Docker. La RLS dipendente dall'identità impostata dall'applicazione non sostituisce una sandbox contro codice che possiede le credenziali del database.
Requisiti e accettazione proposti
Questi sono esiti da validare, non scelte implementative già approvate. Soglie, eccezioni e semantica dei permessi vanno fissate nel grilling prima di rendere i ticket eseguibili.
R1 — Profili supportati e proprietà delle sessioni (SEC-01)
- Descrivere la matrice consentita di esposizione, autenticazione e persistenza; rifiutare le combinazioni incompatibili prima di accettare traffico.
- Con due utenti distinti, verificare elenco, lettura, modifica, resume, artefatti e SSE: un accesso fuori dai diritti deve essere rifiutato senza rivelare contenuti.
- Il percorso personale supportato deve continuare a funzionare; non introdurre un fallback silenzioso al principal locale sul server.
R2 — Contenimento del runtime agente (SEC-02)
- Concordare tool, directory, segreti ed egress necessari a Pi, nonché il livello di fiducia fra gli utenti.
- Dimostrare con fixture controllate che un'azione non autorizzata non accede a risorse di un'altra sessione o a credenziali non necessarie.
- Verificare che il contenimento scelto mantenga funzionanti workflow, gate e resume. Se il confine scelto non garantisce isolamento ostile, documentare e approvare quel limite.
R3 — TLS DWH end-to-end (SEC-03)
- Per ogni driver supportato, verificare che i parametri TLS arrivino al connettore realmente usato.
- CA valida e nome corretto devono consentire la connessione; CA non fidata, nome errato o downgrade vietato devono fallire quando il profilo richiede verifica TLS.
- Eventuali eccezioni personali devono essere deliberate, visibili e prive di fallback automatico.
R4 — Controllo della divulgazione dei valori (SEC-04)
- Applicare la policy approvata prima che risultati LSH e altri campioni raggiungano il prompt, non soltanto nella UI.
- Testare Sensitive Data Flag e Model Data Boundary alle interfacce effettive di uscita; verificare che il valore protetto sia assente, non solo che un helper sia stato chiamato.
- Decidere il comportamento con classificazione mancante, nuovi campi, indici già pubblicati e flag cambiati dopo l'indicizzazione.
- Rispettare il gate di owner acceptance già registrato per il follow-up schema-linking; confermarne lo stato prima di implementare.
R5 — Persistenza, retention e log (SEC-05)
- Inventariare artefatti, tracce Pi, temporanei, log, indici ed esportazioni realmente prodotti.
- Definire abilitazione, contenuto ammesso, accessi, retention e cancellazione per ciascuna classe.
- Una sessione di prova con segreti-canary e dati sintetici deve dimostrare l'assenza dei contenuti vietati; la pulizia deve preservare gli artefatti necessari al resume.
R6 — Revoca e ciclo di vita dell'identità (SEC-06)
- Concordare tempi massimi distinti per revoca applicativa e variazione dei diritti nell'IdP, senza promettere sincronizzazione istantanea non supportata.
- Verificare logout, revoca amministrativa, scadenza, cambio dei gruppi, stream già aperti e riconnessione.
- Stabilire se e come gestire processi in corso quando cambiano i diritti; definire il comportamento durante indisponibilità delle fonti di validità.
R7 — Autorizzazione alle risorse condivise (SEC-07)
- Decidere il perimetro condiviso di workspace, DWH, catalogo e amministrazione.
- Se i diritti sono differenziati, applicarli alle API e alle operazioni di creazione/resume, non soltanto al selettore frontend.
- Se tutti gli utenti autorizzati condividono i dati, renderlo un contratto esplicito senza presentarlo come isolamento multi-tenant.
R8 — Limiti effettivi e disponibilità (SEC-08)
- Fissare limiti per righe, byte, durata, concorrenza e chiamate al modello; valutare quote per utente sul server.
- Verificare SQL con LIMIT assente o eccessivo e risultati voluminosi: il consumo deve essere limitato prima del fetch completo, non soltanto nella risposta.
- Timeout e cancellazione devono rilasciare risorse; una richiesta abusiva non deve impedire il lavoro lecito dell'altro utente entro i limiti concordati.
R9 — Reverse proxy e difese HTTP (SEC-09)
- Dichiarare i proxy fidati e verificare sia il corretto riconoscimento del client sia il rifiuto di header inoltrati da sorgenti non fidate.
- Verificare rate limit, origini ammesse, cookie e protezioni CSRF nei percorsi diretto e HTTPS dietro proxy.
- Definire una policy per gli header di sicurezza e CSP compatibile con frontend e SSE; testare il comportamento effettivo del browser.
R10 — Dipendenze e build (SEC-10)
- Rigenerare l'inventario delle dipendenze effettivamente distribuite, includendo Pi, Python e immagini base; separare runtime e sviluppo.
- Per ogni advisory rilevante, registrare versione, percorso, raggiungibilità, rimedio o accettazione motivata. I conteggi dell'audit storico non sono una baseline aggiornata.
- Rendere riproducibile la risoluzione delle dipendenze concordate e verificare un rebuild; evitare aggiornamenti indiscriminati scollegati dai rilievi.
R11 — Hardening Docker (SEC-11)
- Applicare il minimo privilegio a capability, privilegi, mount scrivibili, rete e risorse, secondo il runtime concordato.
- Verificare che porte e mount esposti corrispondano al profilo; Qdrant, catalogo ed embedding non devono diventare pubblici per effetto di un default inatteso.
- Eseguire uno smoke test di avvio, workflow, manutenzione e arresto con le restrizioni abilitate; documentare le directory che richiedono scrittura.
R12 — Segreti, backup e ripristino (SEC-12)
- Definire chi può leggere e copiare segreti, chiavi e backup; verificare permessi e redazione degli output.
- Concordare la protezione degli archivi esportati e la gestione della chiave: un archivio contenente anche la chiave di decifratura non è protetto da quella sola cifratura.
- Provare ripristino e rotazione su dati sintetici. Il modello di minaccia e l'eventuale rischio accettato devono accompagnare le istruzioni operative.
Decisioni aperte per grill-with-docs
Il seguente elenco è una mappa delle decisioni, non un questionario da somministrare tutto insieme. La skill deve chiedere, a ogni round, soltanto le decisioni i cui prerequisiti sono già risolti.
- Quali profili devono essere supportati e quali minacce devono contenere? Gli utenti server sono reciprocamente fidati?
- Tutti gli utenti vedono gli stessi workspace e dati? Quali operazioni sono amministrative?
- Quale esecuzione di tool è indispensabile a Pi e quale confine di isolamento è sostenibile sul desktop e sul server?
- Quali dati possono raggiungere modelli esterni? Quale policy vale per classificazione assente o incompleta?
- Quale semantica e latenza di revoca servono per built-in, OIDC, SSE e lavori già in corso?
- Quali tracce sono utili al prodotto e alla diagnosi? Con quali durata, accessi e cancellazione?
- Quali limiti di risorse, eccezioni TLS e garanzie sui backup sono necessari nei due contesti?
- Quali rischi bloccano un rilascio, quali sono accettabili temporaneamente e chi ne approva l'accettazione?
- Quali confini pubblici verranno testati, con quali fixture e gate manuali? Quali migrazioni richiedono una prova di rollback?
Le risposte devono distinguere decisione confermata, proposta e fatto da verificare.
Non cambiare implicitamente ADR esistenti. Un nuovo ADR è opportuno soltanto per una decisione
costosa da invertire, sorprendente senza contesto e frutto di alternative reali; può bastare un
titolo e un breve paragrafo. CONTEXT.md resta un glossario, non il contenitore del PRD.
Strategia di test da approvare
Preferire le interfacce pubbliche già esistenti: API HTTP/SSE con due identità, CLI e repository di sessione nel loro percorso reale, connettori DWH, uscita verso i provider e lifecycle Docker. Il numero di confini va mantenuto piccolo senza ridurre tutto a test unitari che non attraversano la protezione da dimostrare.
Ogni requisito approvato deve avere un caso lecito e un caso negativo, con dati sintetici, precondizioni esplicite e risultato osservabile. Usare fixture locali per IdP, DWH e provider; testare l'integrazione reale soltanto in un ambiente di prova autorizzato. I valori numerici dei limiti e delle latenze devono diventare assert misurabili prima dell'implementazione.
Confermare i confini con il maintainer prima di scrivere test. Usare tdd una fetta alla volta:
test rosso sul comportamento, implementazione minima, test verde. Eseguire typecheck e test
mirati durante il lavoro, le suite pertinenti al termine e code-review separando Standards e
Spec contro una base Git fissata. Il passaggio dei test automatici non chiude i gate manuali.
Sequenza proposta, non ancora trasformata in ticket
- Riconfermare i rilievi e chiudere le decisioni che determinano il modello di minaccia.
- Approvare profili, confini di test e criteri di rilascio; aggiornare questo PRD.
- Usare
to-specper la spec concordata e, con autorizzazione, pubblicarla nel tracker Gitea canonico. - Usare
to-ticketsper fette verticali autonomamente verificabili, ciascuna con dipendenze reali e criteri di accettazione; far approvare la scomposizione prima della pubblicazione. - Dare precedenza ai rischi P0 effettivi del profilo scelto, senza attendere il completamento dell'intero hardening per consegnare un controllo verificabile.
- Dopo autorizzazione, implementare un ticket per contesto fresco nel worktree dedicato; chiudere con test, review e istruzioni operative.
Non creare automaticamente una issue per ogni riga della survey: alcune richiedono prima una
decisione, altre possono essere già risolte. Il tracker è Gitea, non il mirror GitHub. Le issue
prodotte da to-tickets dopo approvazione sono già pronte per ready-for-agent, senza ulteriore
triage; questa bozza non lo è. Dopo la pubblicazione, collegare qui la spec canonica e segnalare
che questo documento è la baseline storica, evitando due specifiche concorrenti.
Vincoli, adozione e fuori perimetro
- Oggi sono autorizzati soltanto questi documenti e la loro navigazione. Nessuna modifica a codice, credenziali, container, server, IdP o database.
- La ripresa parte da analisi e grilling. Creazione del worktree, pubblicazione delle issue e implementazione richiedono conferma del maintainer nella sessione futura.
- Per il worktree, verificare base, nome e percorso e preservare tutte le modifiche preesistenti. Non copiare automaticamente
.env, chiavi, dati reali o volumi operativi. - Ogni modifica incompatibile deve descrivere diagnosi preventiva, adozione, migrazione, backup e rollback. Non migrare o cancellare sessioni reali durante i test.
- Preservare workflow a otto fasi, gate umani, resume, persistenza degli artefatti, DWH read-only e Installation Model Catalog come autorità dei modelli.
- Sono fuori perimetro: redesign generico, nuove funzionalità di prodotto non necessarie, sostituzione generalizzata dell'autenticazione, SaaS multi-tenant, pentest remoto e certificazioni di conformità.
- Il problema separato della visibilità dei modelli sul server non fa parte di questo PRD.
Criteri di completamento del futuro intervento
Il lavoro è completo quando tutti i requisiti della spec approvata hanno evidenze e tracciamento, i profili supportati superano i controlli automatici e i gate manuali concordati, le procedure di adozione/ripristino sono verificate e i rischi residui hanno una decisione esplicita dell'owner. Un rilievo storico smentito va chiuso con evidenza, non implementato per inerzia. La chiusura di un sottoinsieme approvato non deve essere presentata come risoluzione di tutti i rilievi.
Appendice — Punti di partenza per riconfermare le evidenze
Questi riferimenti sono indizi della survey, non prescrizioni sui file da modificare. Cercare i simboli e i percorsi correnti alla ripresa; le righe e la distribuzione dei moduli possono cambiare.
| Rilievo | Punti di partenza nel repository |
|---|---|
| SEC-01 | harness/tht/session/repository.py (resolve_principal), filesystem_repository.py, backend/src/config.ts; architettura auth |
| SEC-02 | backend/src/pi/pi-process-manager.ts, provider-credentials.ts, harness/.pi/extensions/tht-gate.js, repository PostgreSQL e identità di connessione |
| SEC-03 | Renderer dell'installazione, harness/tht/config.py, harness/tht/db/connection.py; contratto DWH |
| SEC-04 | harness/tht/cli/search_cmd.py, runtime LSH, worker descrizioni; ADR-0011 e gate in PROJECT_STATE.md |
| SEC-05 | backend/src/pi/managed-config.ts, argomenti del processo Pi, versione Pi nel lockfile e comportamento della libreria effettivamente distribuita |
| SEC-06 | backend/src/auth/session-store.ts, backend/src/routes/sessions.ts, SSE hub; OIDC |
| SEC-07 | backend/src/routes/workspaces.ts, ammissione delle sessioni e policy dei permessi |
| SEC-08 | harness/tht/execute/__init__.py (_inject_limit, fetch dei risultati), timeout e limiti del process manager |
| SEC-09 | backend/src/app.ts, rate limiter del login, configurazione proxy e risposte HTTP del deploy di prova |
| SEC-10 | Lockfile backend/frontend/Pi, installazione Python nell'immagine core e inventario immagini; advisory storici su undici, brace-expansion, protobufjs e relativa dipendenza Pi da rivalutare |
| SEC-11 | Dockerfile e Compose in deploy/, confronto fra core e manutenzione, docker inspect con output sanitizzato solo su ambiente autorizzato |
| SEC-12 | backend/src/workspaces/secret-store.ts, backup/restore in tools/tht; ADR-0002 |
Per le decisioni collegate consultare anche ADR-0010,
ADR-0013,
gli ADR correnti sulla sensitivity e le istruzioni in docs/agents/.