Se un agente propone «rm -rf /tmp» per analizzare lo spazio disco, non mi affido alla sola istruzione data al modello. Nella demo una regola esterna ferma «rm», che non è nella allowlist, prima che il comando arrivi alla shell.If an agent proposes "rm -rf /tmp" to analyze disk usage, I don't rely only on its instructions. In the demo, a rule outside the agent stops "rm", which isn't on the allowlist, before the command reaches the shell.
Progetti / Security
AI Guardian Lab
Un middleware open source tra l'agente LLM e la shell, prima dell'esecuzione.Open-source middleware between the LLM agent and the shell, before anything runs.
$ task: "analizza lo spazio disco" · comando: rm -rf /tmp [1/4] allowlist......... FAIL (rm non in allowlist) >> BLOCKED: binario non ammesso.
$ task: "analyze disk usage" · command: rm -rf /tmp [1/4] allowlist......... FAIL (rm not in allowlist) >> BLOCKED: binary not allowed.
Il problemaThe problem
Cosa ho costruitoWhat I built
Ho scritto un middleware Python tra l'agente e la shell. Nel caso qui sopra basta il primo controllo, la allowlist. Dopo cerco offuscamenti con regex e confronto il comando con il task. Se il caso è ambiguo, interviene anche una verifica LLM. I test automatici girano in CI. Il servizio usa utenti non privilegiati e parte in dry-run; i comandi fuori dalla pipeline non sono coperti.I wrote Python middleware between the agent and the shell. The first check, the allowlist, stops the example above. Next I use regex to check for obfuscation and compare the command with the task. An LLM check handles ambiguous cases. Automated tests run in CI. The service uses unprivileged users and starts in dry-run; commands outside the pipeline aren't covered.
Ruolo: Software Developer (open source), dal 2026. Il codice è pubblico. Non c'è una sandbox forte: in produzione non lo metterei.Role: Software Developer (open source), since 2026. The code is public. There's no strong sandbox: I wouldn't put it in production.
Come l'ho verificatoHow I verified it
Le prove stanno nel repository. I controlli della pipeline sono la allowlist dei binari, le regex sul comando grezzo e normalizzato, la coerenza tra il task e il comando e la verifica LLM solo sui casi ambigui. Il comportamento è fail-closed: se un controllo ha un dubbio il comando non passa, e se la verifica LLM non risponde il comando resta bloccato.The evidence is in the repository. The pipeline checks are the binary allowlist, regex on the raw and normalized command, coherence between the task and the command, and the LLM check only for ambiguous cases. It's fail-closed: if a check has a doubt the command doesn't pass, and if the LLM check doesn't answer the command stays blocked.
I test automatici girano con pytest. La CI esegue pytest, una scansione Bandit non bloccante e uno smoke test Docker. Nel repository ci sono anche il corpus di attacchi, diviso per offuscamento, esfiltrazione, reverse shell e prompt injection, e la configurazione dei container: agente in dry-run di default, utenti non privilegiati, cap_drop: ALL e no-new-privileges.The automated tests run with pytest. CI runs pytest, a non-blocking Bandit scan and a Docker smoke test. The repository also contains the attack corpus, split into obfuscation, exfiltration, reverse shells and prompt injection, and the container setup: agent in dry-run by default, unprivileged users, cap_drop: ALL and no-new-privileges.
I test e il corpus di attacchi sono nel repository; l'esito di ogni run si vede nella CI.The tests and the attack corpus are in the repository; the result of each run is in the CI.
Tech Stack