description:"Guida al rafforzamento della sicurezza per SnapOtter. Sicurezza del container, isolamento di rete, Docker secrets, distribuzione Kubernetes e artefatti di conformità."
SnapOtter elabora i file interamente sulla tua infrastruttura. Invia analytics di prodotto anonime e prive di contenuti e report di crash per impostazione predefinita, per aiutare a migliorare il progetto. Non invia mai i tuoi file, i nomi dei file, il contenuto dei file, l'output OCR, i metadati delle immagini o il testo dei documenti. Il feedback facoltativo viene inviato solo dopo che un utente lo ha inviato, solo quando le analytics sono abilitate, e i campi di contatto sono inclusi solo con esplicito consenso al contatto. Un amministratore può disattivare la raccolta di analytics e feedback con un solo clic in Impostazioni > Sistema > Privacy, senza bisogno di ricostruzione. L'elaborazione dei file resta sempre all'interno del tuo container.
Il container gira come utente non-root dedicato (`snapotter`) con tutte le capacità Linux rimosse tranne il set minimo richiesto. Per la policy completa di divulgazione delle vulnerabilità e l'architettura di sicurezza, vedi [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) su GitHub.
## Rafforzamento del container {#container-hardening}
Il [docker-compose.yml predefinito](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) include il rafforzamento della sicurezza per la produzione. Ecco una descrizione di ciascuna opzione e del perché è importante:
```yaml
services:
SnapOtter:
image:snapotter/snapotter:latest
ports:
# Bind to localhost only for internet-facing deployments:
### Perché `no-new-privileges` non è impostato {#why-no-new-privileges-is-not-set}
`security_opt: [no-new-privileges:true]` è volutamente omesso. L'entrypoint parte come root per correggere la proprietà dei volumi, poi scende all'utente `snapotter` tramite [gosu](https://github.com/tianon/gosu), che richiede setuid. Una volta completata la riduzione dei privilegi, il processo gira come `snapotter` con tutte le capacità rimosse tranne le cinque elencate sopra.
Se usi Kubernetes o il flag `--user` di Docker per eseguire direttamente come non-root (bypassando gosu), `no-new-privileges` può essere abilitato in sicurezza.
### Perché `read_only` non è impostato {#why-read-only-is-not-set}
`read_only: true` non è impostato perché il rimappaggio PUID/PGID scrive su `/etc/passwd` e `/etc/group` all'avvio. Se usi il flag `--user` di Docker o `runAsUser` di Kubernetes invece di PUID/PGID, puoi abilitare in sicurezza un filesystem root di sola lettura.
## Isolamento di rete {#network-isolation}
Durante il normale funzionamento, il container effettua **zero connessioni di rete in uscita**. Tutta l'elaborazione dei file avviene localmente usando librerie integrate.
L'unica eccezione sono i **download dei modelli AI**: quando un utente installa un bundle di funzionalità AI tramite l'interfaccia, il container scarica l'archivio del bundle pre-costruito da Hugging Face, più alcuni singoli file di modelli da GitHub Releases, Google Storage e PyPI. Questi download avvengono una volta per bundle e sono memorizzati nel volume `/data`.
**Raccomandazioni sul firewall:**
| Scenario | Regola in uscita |
|---|---|
| Air-gapped (senza AI) | Blocca tutto il traffico in uscita dal container |
| Bundle AI necessari | Consenti HTTPS verso `huggingface.co`, `*.xethub.hf.co`, `cdn-lfs.huggingface.co`, `github.com`, `objects.githubusercontent.com`, `storage.googleapis.com`, `pypi.org`, `files.pythonhosted.org` durante l'installazione, poi blocca |
| Dopo l'installazione AI | Blocca tutto il traffico in uscita, i modelli sono memorizzati nella cache locale |
Gli archivi dei bundle vengono serviti dall'archiviazione Xet di Hugging Face, che trasferisce in parallelo attraverso gli endpoint `*.xethub.hf.co` ed è ciò che rende veloci i download di bundle da diversi GB. Se il tuo firewall consente `huggingface.co` ma blocca `*.xethub.hf.co`, le installazioni riescono comunque ma ripiegano su un download a flusso singolo più lento, quindi metti in allowlist gli host Xet per restare sul percorso veloce. Le installazioni completamente offline possono saltare tutto questo e usare invece l'[Importazione di bundle offline](/it/guide/deployment).
Per la configurazione del reverse proxy (Nginx, Traefik, Caddy, Cloudflare Tunnels), vedi la [guida alla distribuzione](/it/guide/deployment#reverse-proxy).
## Docker Secrets {#docker-secrets}
Per le distribuzioni in produzione, evita di passare i segreti come variabili d'ambiente in chiaro. L'entrypoint supporta la convenzione `_FILE` di Docker: monta un segreto come file e imposta la corrispondente variabile `_FILE` sul suo percorso.
L'entrypoint rileva quando il container è già in esecuzione come non-root (ad es. tramite `runAsUser` di Kubernetes) e salta automaticamente la riduzione dei privilegi gosu. In quel caso non può fare il chown dei volumi montati da solo, quindi verifica che siano scrivibili ed esce subito con indicazioni pratiche se non lo sono, vedi [Permessi di archiviazione](/it/guide/deployment#storage-permissions) per `fsGroup` e le configurazioni con UID estraneo (TrueNAS, OpenShift).
**SecurityContext del pod consigliato:**
```yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:snapotter
spec:
replicas:1
selector:
matchLabels:
app:snapotter
template:
metadata:
labels:
app:snapotter
spec:
securityContext:
runAsNonRoot:true
runAsUser:999
runAsGroup:999
fsGroup:999
containers:
- name:snapotter
image:snapotter/snapotter:latest
ports:
- containerPort:1349
securityContext:
allowPrivilegeEscalation:false
capabilities:
drop:[ALL]
resources:
requests:
cpu:"1"
memory:2Gi
limits:
cpu:"4"
memory:6Gi
livenessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:60
periodSeconds:30
timeoutSeconds:5
readinessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:10
periodSeconds:10
timeoutSeconds:5
volumeMounts:
- name:data
mountPath:/data
- name:workspace
mountPath:/tmp/workspace
volumes:
- name:data
persistentVolumeClaim:
claimName:snapotter-data
- name:workspace
emptyDir:
medium:Memory
sizeLimit:2Gi
```
Poiché `runAsUser: 999` è impostato a livello di pod, l'entrypoint salta del tutto gosu. Questo consente le capacità `allowPrivilegeEscalation: false` e `drop: [ALL]` senza conflitti.
Per il dimensionamento delle risorse, vedi [Requisiti hardware](/it/guide/deployment#hardware-requirements).
## Backup e ripristino {#backup-and-recovery}
Lo stato persistente è suddiviso su due volumi:
| Volume | Contenuti | Critico? |
|---|---|---|
| `SnapOtter-pgdata` | Database PostgreSQL (utenti, impostazioni, pipeline, job, log di audit) | Sì |
In alternativa, ferma lo stack e crea uno snapshot del volume `SnapOtter-pgdata`:
```bash
docker compose down
docker run --rm -v SnapOtter-pgdata:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/snapotter-pgdata.tar.gz -C /data .
```
### Backup dei file utente {#user-files-backup}
```bash
# Snapshot the app data volume (excluding re-downloadable AI models)
docker run --rm -v SnapOtter-data:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/snapotter-files.tar.gz \
--exclude='ai' --exclude='venv' -C /data .
```
I modelli AI ammontano fino a circa 24 GB su tutti i bundle. Poiché sono riscaricabili, escludi `/data/ai/` e `/data/venv/` dai backup per risparmiare spazio. Solo il database e i file utente sono critici.
## Artefatti di conformità {#compliance-artifacts}
Ogni release di SnapOtter include i seguenti artefatti di sicurezza:
| Revisione delle dipendenze | Nativa di GitHub | Controllo per PR, fallisce sulle aggiunte ad alta gravità |
| Audit delle dipendenze Python | pip-audit | Log di esecuzione CI a ogni push |
| Policy di sicurezza | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) nel repository |
| Aggiornamenti delle dipendenze | Dependabot | PR settimanali automatiche per npm, pip, Docker, Actions |
**Eseguire la tua scansione:**
Scarica l'SBOM dalla release e scansionalo con lo strumento che preferisci:
```bash
# Scan with Grype using the CycloneDX SBOM
grype sbom:snapotter-v1.17.2-sbom.cdx.json
# Scan with Trivy using the SPDX SBOM
trivy sbom snapotter-v1.17.2-sbom.spdx.json
# Scan the Docker image directly
trivy image snapotter/snapotter:1.17.2
```
::: info
L'SBOM e la scansione delle vulnerabilità riflettono l'immagine esatta pubblicata per quella release. I bundle di modelli AI installati dopo la distribuzione non sono inclusi nell'SBOM poiché vengono scaricati a runtime.