Harness e sandbox per agenti: TrueForge e smolvm

TrueForge è un harness open source in TypeScript che tiene il ciclo di esecuzione, i tool MCP, le approvazioni e i segreti. smolvm è una CLI in Rust che avvia microVM con kernel guest separato su libkrun, con allowlist di egress nel file di configurazione. Sotto ci sono cinque livelli di isolamento diversi, da seccomp alla VM completa, e ognuno ferma cose diverse.

AICybersecurityAIAgenti AISicurezzaSandboxmicroVMOpen SourceHarnessRust
Sommario
  1. TrueForge, il livello harness
  2. smolvm, il livello di isolamento
  3. I cinque livelli, e cosa ferma ciascuno
  4. Quello che smolvm dichiara di non proteggere
  5. Come si compongono i due strati
  6. Cosa ne pensiamo
  7. Fonti
Quattro dati su TrueForge, smolvm e i livelli di isolamento per gli agenti
Letture del 20 agosto sui repository. Fonti in fondo.

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.

LivelloStrumentiCosa separa
Filtro di sistemaseccomp-bpf, LandlockRestringe le chiamate del processo, kernel condiviso
Namespacebubblewrap, nsjailIsola viste di filesystem, rete e PID, kernel condiviso
Kernel applicativogVisorIntercetta le syscall in userspace
microVMlibkrun, Firecracker, microsandboxKernel guest separato, confine hardware
VM completaKata ContainersKernel 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.

Fonti

Vuoi supporto?Sei sotto attacco?Stato dei servizi
Vuoi supporto?Sei sotto attacco?Stato dei servizi