Documentazione · riferimento
Sicurezza e note operative
Cosa sapere per far funzionare bene Pyrite in rete locale, cosa fa il motore per proteggere app e dati e cosa resta compito di chi costruisce e approva le app.
01 /Stesso indirizzo per portale e app
L'accesso unico si basa su un cookie di sessione del motore. Il browser lega i cookie al nome del server e non alla porta, quindi portale e app condividono la sessione solo se vengono aperti con lo stesso nome.
Se apri il portale con http://192.168.1.20:8080/ e un'app con http://server-app:8101/, per il browser sono due posti diversi e l'app chiede di nuovo il login. Scegli una forma, o sempre l'IP o sempre il nome, e usala dappertutto: preferiti, collegamenti, email. Gli indirizzi di questo esempio sono inventati.
Se ogni app ha il suo nome (Regole di rete), chi apre un'app senza essere entrato passa dal portale, scrive la password una volta e torna da solo all'app: nessun cookie vale per tutto il dominio. Con nome e porta non cambia niente (vedi Accesso: un solo accesso, tentativi sbagliati, la console).
02 /Firewall e porte
- Al primo avvio Windows chiede se consentire
pyrite.exesulla rete, con la finestra «Sicurezza di Windows». Scegli «Reti private» e consenti. Lo chiede di nuovo per ogni cartella e per ogni file nuovo del programma, per esempio se sposti il programma in un'altra cartella (la regola di prima resta nel firewall finché non la togli). - Dagli altri PC devono essere raggiungibili la porta del motore (di solito la 8080) e le porte pubbliche delle app, quelle scritte nelle loro schede.
- Pyrite legge lo stato del firewall di Windows e può creare la sua regola: l'installazione del servizio la crea, il comando
pyrite.exe firewall status | open | closela gestisce e le Regole di rete hanno un riquadro «Firewall di Windows» (vedi Il firewall di Windows). - Le porte interne delle app (la porta pubblica più 1000) rispondono solo sul server e solo al motore: non vanno aperte.
- Con un firewall diverso da quello di Windows, apri le stesse porte solo verso la rete interna.
03 /Solo rete interna
Senza un certificato il motore lavora in HTTP e password e dati viaggiano in chiaro sulla rete locale. L'HTTPS si accende dalla pagina Certificati: un certificato per il motore e per tutte le porte delle app (CA aziendale, file .pfx o .pem, o una CA interna creata da Pyrite). Si può avere anche Let's Encrypt (con il DNS di Cloudflare o con la porta 443) e più di un certificato: vedi HTTPS e certificati. Si possono aprire alcune app a internet (Regole di rete), ma solo con HTTPS acceso, un'app alla volta e solo per dati non sensibili. La console da internet non si apre mai.
04 /Amministrazione centralizzata
- Nessuno entra come amministratore direttamente in un'app. L'indirizzo
/_/sulla porta di un'app rimanda alla scheda Dati dell'app nella console del motore, e le chiamate da amministratore sulle porte delle app vengono respinte. - Ogni app ha un amministratore tecnico con una password casuale che nessuno conosce. Lo usa solo il motore.
- Anche nel PocketBase del motore nessuno entra direttamente:
/_/porta alla console, e il superuser del motore è un account tecnico con una password casuale, che non è scritta da nessuna parte. L'eseguibile non ha il comandosuperuserdi PocketBase. - Di conseguenza un Proprietario della console apre tutte le app, e un Admin le app che gestisce. Dai il livello di Proprietario a poche persone, con password lunghe.
- La registrazione libera, che PocketBase lascia aperta di serie, nella rubrica del motore è chiusa: le persone le aggiunge l'amministratore.
05 /La console e i livelli
- Nella console entrano solo i Proprietari e gli Admin, con il loro account della rubrica; le persone di livello Utente si fermano alla pagina d'accesso.
- Ogni operazione della console passa da un'unica tabella di regole, che dice quale livello serve e su quale app: quello che non è nella tabella è negato.
- Le chiavi della console stanno solo nella memoria del motore e viaggiano in un'intestazione della richiesta, non in un cookie. La sessione si chiude da sola dopo 30 minuti senza uso (il tempo si cambia nelle Regole di rete, da 5 minuti a 12 ore) e non dura mai più di 12 ore dall'accesso; un riavvio del motore le chiude tutte (vedi La console si chiude da sola).
- A ogni richiesta il motore ricontrolla la persona: se è stata disattivata, se ha cambiato password o livello, o se ha perso un'app, le sue chiavi smettono di valere.
- I livelli sono quattro: Proprietario, Admin Persone, Admin App e Utente. L'Admin Persone gestisce le persone e i gruppi della sua unità e non vede le app; l'Admin App gestisce le sue app e non vede le persone. Chi era Admin prima resta «Admin (come nella 0.7.5)»: lavora solo sulle sue app e sulle persone di livello Utente, con gli stessi limiti di prima. Chi amministra senza essere Proprietario non vede i Proprietari: dove comparirebbero legge «Proprietario», senza email. Le ricerche nella rubrica che passano dalle relazioni gli sono rifiutate (vedi La console e i livelli).
- Le unità tengono separati i clienti su un solo motore: quello che è di un'altra unità «non esiste» per chi non la amministra, e a deciderlo è il motore, non la pagina (vedi Più clienti su un motore: le unità).
- La doppia autenticazione è un codice a sei cifre dal telefono, dopo email e password, per la console e per il portale. Cinque codici sbagliati in 15 minuti fermano il codice di quella persona per 15 minuti. Un Proprietario può toglierla a chi ha perso il telefono (vedi Doppia autenticazione).
- L'ultimo Proprietario attivo non si può eliminare, disattivare o spostare a un altro livello.
- Le app caricate da un Admin non si avviano finché un Proprietario non le approva.
- Le pagine «Avanzate» (impostazioni di PocketBase, console SQL e, se l'amministratore ha creato raccolte sue, il registro dati) sono solo dei Proprietari: lì si cambia il registro del motore senza i controlli delle pagine di Pyrite. Le raccolte che le pagine di Pyrite gestiscono (persone, gruppi, accessi, app, home del portale, impostazioni del motore, analisi) non compaiono nel registro dati, le loro API native di PocketBase rispondono 403 alla console tranne quelle che usano le pagine di Pyrite, e l'import delle raccolte non le cambia. L'elenco «Superuser IPs» non si vede e non si cambia dalla console. «Impersonate» è chiuso a tutti.
L'import di persone e gruppi da Excel (pagina Persone) rispetta i livelli: un Admin aggiunge solo persone di livello Utente, solo in gruppi che può modificare e solo con accessi alle app che gestisce (per lui un'app non sua «non esiste»); nessuno può importare un Proprietario. È solo aggiunta e tutto o niente; le password provvisorie sono in un file che si scarica una volta, per 10 minuti, e non finiscono in eventi, risposte o note.
L'import intelligente della scheda «Importa» scrive direttamente nel database dell'app, come il server: le regole API e le rotte dell'app non contano. Per questo un'app che tiene i dati in ordine con le sue rotte o i suoi hook (spostamenti, storici, stati) deve dire in app.json, campo import.consoleCollections, le sole raccolte in cui la console può importare e annullare ([] = nessuna); senza, la scheda avvisa che si vedono tutte. È tutto o niente, in due tempi, con il tetto di 50.000 righe e 60 secondi di scritture, e «Annulla» toglie tutto l'import ma si ferma se record di altri sono collegati a quelli importati o se dei record sono cambiati dopo. Dalle pagine delle app serve una ricetta approvata dall'amministratore (toolAccess), con i limiti di righe. I file JSON si leggono con tetti di dimensione (128 MB il file, 16 MB per elemento).
06 /Accessi e sessioni
- Ogni richiesta a un'app con login passa dal motore, che controlla sessione e accesso. Per questo togliere un accesso ha effetto subito.
- Il cookie di sessione del motore non arriva mai alle app: il motore toglie ogni suo cookie, tranne quello della lingua, prima di inoltrare la richiesta, anche sulle porte delle app aperte a tutti.
- Il token che l'app usa deve appartenere alla stessa persona della sessione del portale. Se non corrisponde, la richiesta viene respinta.
- Dentro le app con login l'identità è bloccata: email, nome e password vengono dalla rubrica, dall'app non si cambiano e non si creano utenti. Nessuno può cambiare il proprio ruolo.
- Le richieste che cambiano qualcosa usando la sessione del portale, come l'accesso al portale e i caricamenti di «Prova import», vengono accettate solo se partono dalle pagine del motore: la pagina di un'app su un'altra porta non le può far partire al posto della persona.
- Il motore conta le password sbagliate per ogni indirizzo vero, anche dietro un tunnel. Da internet bastano 5 errori in 15 minuti per bloccare quell'indirizzo, e 10 errori sulla stessa email bloccano quell'email per un'ora; dalla rete locale si entra sempre. La console ha un conto suo. Le soglie si cambiano in Regole di rete (vedi Accesso).
07 /Le chiusure di sicurezza delle app
Ogni app con database gira in un processo separato, con i suoi dati. In più il motore la chiude dentro tre recinti:
- Una chiave per ogni app. Il motore parla con ogni app con una chiave sua, diversa da quella delle altre. L'app la riceve all'avvio e la toglie subito dalle variabili d'ambiente, così i suoi script non la vedono.
- Porta interna chiusa. La porta interna di un'app risponde solo alle richieste che arrivano dal motore con la chiave giusta. Un'altra app, o un altro programma sul server, non la può usare per scavalcare la porta d'ingresso.
- Script confinati. Gli script dell'app (hook e migrazioni) non avviano programmi e non chiudono il processo. Leggono file solo dentro la cartella dell'app e li scrivono solo nella sua cartella dei dati,
state: la schedaapp.json, il codice inreleasee i log per loro sono in sola lettura, quindi un'app non può cambiarsi da sola accesso, ruoli o strumenti. Non possono nemmeno usare il database per aprire o scrivere file fuori dalla cartella. Non passano dai collegamenti: un percorso che attraversa un collegamento simbolico o una giunzione di Windows dentro la cartella dell'app è rifiutato, anche se porta dentro la cartella. Fa eccezione solo la cartellastatestessa, che l'amministratore può spostare su un altro disco con una giunzione (vedi dati, backup e spazio su disco).
Gli strumenti del motore che le app usano dai loro script, come l'import, lavorano dentro gli stessi confini: file della cartella dell'app e database dell'app.
Un'app non può chiamare il motore (console, portale) né un'altra app dello stesso server: riceve un rifiuto (403) e nella console compare un evento. Il limite, detto chiaro: il recinto riduce molto quello che uno script può fare, ma è una difesa dentro il programma. Lo script gira nello stesso processo del motore di quell'app, con lo stesso utente di Windows. La garanzia piena, un utente di Windows per ogni app, non c'è in questa versione: vedi Che cosa può fare un'app.
Rete in uscita
Un quarto recinto riguarda quello che gli script dell'app chiamano fuori dal server. Gli script raggiungono solo gli indirizzi che l'app dichiara in app.json, campo network (allow: in https; allowHttp: anche in http, solo per sistemi interni che non hanno https). Senza network non raggiungono nessun indirizzo. Il motore controlla anche l'indirizzo vero dopo la risoluzione del nome, e un nome scritto per intero può portare anche a un server della rete interna (con l'asterisco solo indirizzi pubblici). La scheda «Rete in uscita» di ogni app ha due modi: Blocca e Avvisa (passa tutto, e il motore conta quello che bloccherebbe). Le app partono in Blocca. La pagina AI mostra le chiamate ai modelli AI e i costi.
Rotte lente
Il motore aspetta al massimo 4 minuti e 50 secondi la risposta di una rotta degli script di un'app. Poi risponde lui con un 504 dal testo chiaro (un 502 se l'app chiude la connessione senza rispondere, anche di colpo); un'app ferma o in riavvio dà il solito 503. Il motore non ripete mai una richiesta già inviata: la rotta può aver finito il lavoro lo stesso, quindi prima di riprovare si controlla. Il 504 e il 502 lasciano un avviso nello Storico del motore. Il motore riusa le connessioni verso le app, così sotto carico non dà falsi «non disponibile».
08 /Cosa il motore non controlla
Il motore decide chi entra in un'app e la tiene nel suo recinto. Il resto dipende dall'app e da chi la approva.
- Cosa una persona vede e modifica dentro l'app lo decidono le regole dell'app (le API rules di PocketBase) e il suo codice. Nascondere un pulsante non protegge i dati: servono regole sul server. Prima di aprire un'app alle persone, prova a usarla con un ruolo basso e controlla che non veda più del dovuto. Lo standard per gli agenti dice quali regole sono obbligatorie e cosa provare.
- Dentro i propri dati un'app fa quello che il suo codice dice: un hook sbagliato può cancellare o cambiare i record dell'app. Prima di attivare un'app nuova leggi le note di consegna e guarda cosa fanno i suoi hook.
- L'import dalla scheda «Importa» scrive direttamente nel database dell'app: valgono i controlli dei campi, non le regole automatiche che l'app applica quando una persona inserisce un record dalle sue pagine.
- In modo Avvisa la rete in uscita non blocca niente; lo stesso vale per le modifiche concorrenti (due persone che cambiano lo stesso record insieme) se la scheda dice
"concurrency": "warn". Il motore conta soltanto quello che bloccherebbe: per essere protetti servono Blocca e"strict"(vedi la schedaapp.json). - Il limite di memoria della scheda è indicativo: su Windows non impedisce a un'app di usarne di più.
- «Carica app» controlla davvero il pacchetto zip (dimensioni, percorsi, collegamenti, scheda, porte, cartelle), ma i punteggi dei passi «Controllo di sicurezza» e «Compatibilità con lo standard» in questa alpha sono solo indicativi (non sono un controllo di sicurezza): non leggono il codice. L'app si installa spenta proprio perché l'amministratore la controlli prima di avviarla; se l'ha caricata un Admin, resta ferma finché un Proprietario non la approva.
- Le app ad accesso libero sono aperte a chiunque sia in rete. Mettici solo quello che può leggere chiunque. Nascondere una tessera nella home del portale non cambia chi può aprire l'app.
- Le unità separano persone, gruppi e app per il motore, ma gli script delle app di tutte le unità girano sullo stesso computer. Non caricare script scritti da qualcuno di cui non ti fidi contando solo sul recinto (vedi Che cosa può fare un'app).
09 /Credenziali e password
- Il primo Proprietario si crea al primo avvio, dalla pagina di primo avvio: si apre da qualunque computer della rete, mai da internet, e solo finché un Proprietario non c'è. Chiede un codice che Pyrite stampa sul server, così nessun altro della rete può prendersi il motore prima di te. Dopo, quella pagina porta alla console. Proteggi gli account dei Proprietari con password lunghe.
- Le password iniziali create con «Importa dalle app» si vedono una volta sola. Consegnale di persona o con un canale riservato.
- Le password delle persone seguono le regole del motore (maiuscola, minuscola, numero, carattere speciale, lunghezza minima nelle Impostazioni del motore). Chi riceve una password dall'amministratore la cambia al primo accesso; ognuno la può cambiare dal portale. Ad Admin e Utenti la reimposta l'amministratore (un Proprietario, oppure un Admin per le persone di livello Utente).
- Un Proprietario che ha dimenticato la password la rimette da solo: con un'email, se la posta del motore è impostata e l'indirizzo dell'applicazione è quello vero (il collegamento porta alla pagina del motore, vale 30 minuti e una volta sola), oppure con il comando
pyrite.exe owner reset EMAILsul server. Conowner create, sempre sul server, si crea un Proprietario: chi può lanciare comandi sul server può quindi entrare nella console, e il server va tenuto in un posto sicuro.
10 /Dati, backup e spazio su disco
- I dati di ogni app stanno in
apps\<id>\state, quelli del motore incontrol\pb_data. Sono le cartelle da proteggere. - Se i dati di un'app devono stare su un altro disco, al posto della cartella
apps\<id>\statesi può mettere una giunzione di Windows (mklink /J) che porta alla cartella nuova, fuori daapps. Si fa con l'app ferma: prima si copiastatenel posto nuovo, poi si toglie l'originale, si crea la giunzione e si riavvia l'app. Script, import, backup e ripristino continuano a funzionare. Vale solo perstate: un collegamento più in basso (per esempio sustate\pb_data) o in un'altra parte della cartella dell'app gli script e l'import lo rifiutano. Prima di archiviare un'app così, rimettistateal suo posto: l'archiviazione non copia la giunzione e si ferma con «copia non riuscita» (l'app resta ferma, ma intatta). - I backup restano sul disco del motore. Per metterli al sicuro accendi la copia su una cartella di rete (Impostazioni del motore → Copia dei backup su una cartella di rete): ogni giorno li copia su un NAS o un altro disco, controllando ogni file con SHA-256. Senza, scaricane una copia con regolarità e conservala altrove.
- Le copie di sicurezza create dai ripristini (il motore ne tiene le ultime 3 per app), quelle del registro fatte prima di un aggiornamento (
pre_migrazione_<data>.zip), i punti di ripristino dell'aggiornamento del motore incontrol\aggiornamentie le app inarchiviooccupano spazio. Le cartelleritorno_<data>dicontrol\aggiornamenticontengono dati personali e i dati scritti nelle app dopo l'aggiornamento: il motore non le cancella mai, vanno tolte a mano quando non servono più. Le chiavi dei certificati stanno incontrol\certificati, aperta solo a SYSTEM, agli Administrators e all'account del motore, e non entrano nei backup. - I file caricati in «Prova import» stanno in
control\tmp_import, fino a 100 MB l'uno e al massimo 10 per persona, e si cancellano da soli dopo due ore dall'ultimo uso. - Le misure si conservano 30 giorni, poi il motore le elimina. Gli eventi del motore stanno nello storico (
control\storico), che dalla console nessuno cancella: di serie dura un anno e un Proprietario può allungarlo fino a dieci anni, ma non accorciarlo (vedi Lo storico del motore).