Sommario

Cybersecurity
Consulenza CISO-as-a-service: postura, roadmap di remediation, supporto continuativo.
Scopri →
Servizi & Sistemi Linux
Domini, hosting, PEC, infrastruttura email, servizi di rete e sistemi Linux. Assistenza e gestione dell'infrastruttura Open Source.
Scopri →Un agente che lavora da solo tocca due strati che vanno progettati separatamente. Sopra c’è l’harness, che tiene il ciclo, gli strumenti, i segreti e le approvazioni, e di cui abbiamo scritto in harness engineering. Sotto c’è il confinamento, cioè dove il codice viene davvero eseguito.
Due progetti usciti in questi mesi occupano un livello ciascuno.
TrueForge, il livello harness
TrueForge è di TrueFoundry, in TypeScript, licenza MIT, repository aperto il 23 luglio 2026, con 2.178 stelle alla lettura del 20 agosto. Si descrive come “the open-source agent harness - the runtime layer that turns an LLM into a working agent”.
Quello che tiene lo dice l’elenco: chiamate al modello, tool MCP, skill, sandboxing, approvazioni, gestione del contesto e stato di sessione. Si espone in tre modi, una UI di chat, una API HTTP con SDK TypeScript e una UI SDK integrabile.
Tre scelte sono interessanti per chi guarda alla sicurezza.
I checkpoint umani sono parte del runtime e non un innesto: approvazione dei tool, domande all’utente e UI generativa dentro la chat. Chiedere conferma prima di un’azione irreversibile è più facile da tenere quando è il ciclo a prevederlo.
La sandbox è un tool, provisionata solo quando serve, e oggi il provider è Daytona. Sulla stessa riga il README dice “Secrets stay in the harness”: il codice viene eseguito altrove, le credenziali restano nello strato che decide.
La configurazione parte da cataloghi YAML per modelli, server MCP, skill e sandbox. Un elenco dichiarato di cosa un agente può usare è anche l’elenco da rivedere in un audit.
Il resto è ingegneria del contesto, con subagent, caricamento differito dei tool, offload dei risultati grossi e compaction, e due modalità di esercizio: locale a processo singolo con SQLite, oppure Postgres più Redis con Docker Compose o Helm.
smolvm, il livello di isolamento
smolvm è in Rust, licenza Apache-2.0, repository aperto il 18 dicembre 2025, con 5.562 stelle al 20 agosto. La descrizione è “Ship and run software with isolation by default”.
Ogni workload gira in una VM con kernel guest separato, su Hypervisor.framework su macOS, KVM su Linux e Windows Hypervisor Platform su Windows. Il VMM è libkrun e il kernel guest arriva da libkrunfw. Le immagini sono OCI, quindi si parte da qualunque immagine su Docker Hub o ghcr.io senza un daemon Docker.
I default sono 4 vCPU e 8 GiB di RAM, con memoria elastica via virtio balloon: l’host impegna quello che il guest usa davvero e recupera il resto. I thread vCPU dormono nell’hypervisor quando sono inattivi.
La macchina si dichiara in un Smolfile in TOML, con immagine, risorse, mount, porte e comandi di setup. Due dettagli che pesano più di quanto sembri.
Il primo è la politica di rete. La rete è disattivata per default, e quando si accende esiste una allowlist esplicita:
[network]
allow_hosts = ["api.stripe.com", "pypi.org"]
Per un agente che esegue codice generato da un modello, l’egress è il vettore che si dimentica per ultimo, e averlo dichiarato in un file che sta nel repository lo rende rivedibile come qualunque altra configurazione.
Il secondo è che le chiavi sconosciute vengono rifiutate invece che ignorate: un refuso fallisce alla creazione della macchina, non silenziosamente a runtime.
C’è poi lo snapshot: una macchina configurata a mano si impacchetta in un file .smolmachine e si spinge su un registry OCI, senza scrivere un Dockerfile.
I cinque livelli, e cosa ferma ciascuno
Sotto la parola sandbox stanno cose molto diverse. Ordinati per quanto isolano, e per quanto costano.
| Livello | Strumenti | Cosa separa |
|---|---|---|
| Filtro di sistema | seccomp-bpf, Landlock | Restringe le chiamate del processo, kernel condiviso |
| Namespace | bubblewrap, nsjail | Isola viste di filesystem, rete e PID, kernel condiviso |
| Kernel applicativo | gVisor | Intercetta le syscall in userspace |
| microVM | libkrun, Firecracker, microsandbox | Kernel guest separato, confine hardware |
| VM completa | Kata Containers | Kernel e runtime container completi |
La riga che si fraintende più spesso è gVisor, e il progetto lo mette in chiaro da sé: “gVisor is not a syscall filter (e.g. seccomp-bpf), nor a wrapper over” un altro runtime. È un kernel applicativo scritto in Go che gira in userspace e implementa l’interfaccia Linux, quindi il kernel dell’host vede solo quello che gVisor gli passa.
Il salto vero sta fra la terza e la quarta riga. Sopra, un’evasione punta al kernel dell’host, che è condiviso. Sotto, il guest ha un kernel proprio e per arrivare all’host deve passare dall’hypervisor. È lo stesso ragionamento per cui AWS costruì Firecracker, oggi a 36.165 stelle, per far girare codice di clienti diversi sulla stessa macchina.
Per gli agenti la scelta si restringe in fretta. Un agente che compila, installa pacchetti e lancia processi ha bisogno di una superficie Linux ampia, e su quella superficie i filtri di sistema da soli lasciano scoperto troppo. Le microVM costano di più in memoria e avvio, e in cambio spostano il confine su una superficie molto più stretta.
Fra i servizi gestiti, E2B è Apache-2.0 con 13.486 stelle e nasce come sandbox cloud per agenti, mentre Daytona, quello che TrueForge usa oggi, sta a 71.955.
Quello che smolvm dichiara di non proteggere
Il README ha una sezione Security Model che vale più di molte pagine di documentazione, perché elenca i limiti invece di ometterli.
La CLI e i processi VMM girano con i permessi dell’utente che li invoca, e quell’account, l’host, l’hypervisor, libkrun e smolvm stesso stanno nella base di calcolo fidata. Le directory passate con --volume sono esposte al guest di proposito, e il progetto avverte di non montarci segreti. Il forwarding dell’agente SSH non copia le chiavi private nel guest, ma consente al guest di chiedere firme finché la VM è viva.
C’è anche un punto che riguarda la catena di distribuzione: gli archivi di rilascio pubblicano checksum SHA-256 e l’installer rifiuta un mismatch quando il file dei checksum è disponibile, ma le release non sono firmate né accompagnate da attestazioni di provenienza, e l’installer procede se il file dei checksum non si scarica. L’installazione consigliata è un curl | bash, quindi chi porta smolvm in un ambiente di lavoro scarica il binario dalle release e ne verifica il checksum a mano.
Come si compongono i due strati
La divisione dei compiti che i due progetti suggeriscono è netta, e regge anche cambiando strumenti.
L’harness tiene ciò che non deve mai entrare nella sandbox: credenziali, politica di approvazione, elenco dei tool consentiti, storico delle sessioni. La sandbox tiene ciò che non deve mai uscire: il processo che esegue codice non revisionato, il filesystem su cui scrive e la sua rete.
Il confine fra i due è la superficie da progettare, ed è la stessa domanda che ci eravamo posti guardando DeepSeek Harness, dove i plugin arrivano da un riferimento GitHub risolto da pnpm senza firma né allowlist, e in sicurezza e governance del ciclo agentico.
Cosa ne pensiamo
Il modo più economico di sbagliare qui è trattare “sandbox” come una casella da spuntare. Fra un filtro di syscall e una microVM con kernel proprio ci sono tre livelli, e la differenza si vede solo il giorno in cui qualcosa evade.
Il criterio pratico che ne ricaviamo è di partire dalla domanda su cosa esegue l’agente. Se esegue solo strumenti che avete scritto voi, un confinamento a namespace con una allowlist di egress copre già molto. Se esegue codice che il modello ha appena generato, o pacchetti presi da un registry pubblico, il kernel condiviso diventa il punto debole e la microVM è il livello giusto.
Sulla rete la regola è più semplice e viene ignorata più spesso: negare per default e dichiarare le destinazioni in un file versionato. Un agente che può risolvere qualunque host ha un canale di esfiltrazione, indipendentemente da quanto è isolato il filesystem.
E la parte che nessuno dei due strati risolve resta la catena di fornitura di quello che ci si mette dentro. Un binario installato con curl | bash da release non firmate, o un plugin risolto da un riferimento a un repository, entrano nella base fidata prima ancora che la sandbox si accenda.
