09. Безопасность
Безопасность AstraCode строится на трёх независимых уровнях:
- Sandbox — изоляция выполнения команд от файловой системы и сети.
- Approvals — пользовательские разрешения на потенциально опасные операции.
- Secrets — криптографическая защита API-ключей и токенов.
1. Sandbox: три режима
read-only
Наиболее строгий. Процессы видят всю файловую систему read-only (включая проект), не могут писать никуда. Сеть отключена. Полезно для анализа кода без побочных эффектов.
workspace-write (рекомендуемый для разработки)
Среднеуровневый. Чтение FS неограничено. Запись разрешена только в writable_roots (по умолчанию — корень проекта и /tmp). Метаданные проекта (.git, .agents, .astracode) защищены от записи даже здесь — никакие команды не могут случайно поломать git-историю.
Сеть управляется отдельно:
[sandbox_workspace_write] writable_roots = ["/home/timur/work/myproject"] network_access = false exclude_tmpdir_env_var = false # true → не разрешать запись в $TMPDIR exclude_slash_tmp = false # true → не разрешать запись в /tmp
danger-full-access
Отключает sandbox полностью. Используется только для явно доверенных операций. Эскалация в этот режим требует подтверждения пользователя (через approvals).
В конфиге:
sandbox_mode = "workspace-write"
2. Linux: bwrap + seccomp + landlock
Bubblewrap (основной механизм)
Создаёт изолированные namespaces (user, PID, network, mount). Корневая FS монтируется как read-only (--ro-bind / /), затем накладываются writable bind-mounts для разрешённых путей.
Вложенные разрешения поддерживаются — например, /home/me/work/project writable, но /home/me/work/project/.git сверху накатывается read-only.
Опции:
- Стартует системный bwrap из PATH, если есть и работает (поддерживает unprivileged user namespaces).
- Fallback: встроенный vendored bwrap (распаковывается в ~/.astracode/).
Seccomp
Дополнительно к bwrap включается seccomp-фильтр через PR_SET_NO_NEW_PRIVS:
- Блокирует setuid, setgid, capset (эскалация привилегий).
- При выключенной сети (network_access = false) блокирует системные вызовы создания сокетов (кроме AF_UNIX для shell-escalation).
Landlock (legacy)
Альтернатива bwrap для систем без user namespaces (например, ограниченные контейнеры, WSL1 не поддерживается совсем). Включается фичей в конфиге:
[features] use_legacy_landlock = true
(Флаг --use-legacy-landlock на основном бинаре не публичный — это скрытый флаг внутреннего бинаря astracode-linux-sandbox.)
Landlock — это in-kernel LSM, ограничивающий FS-доступ без namespaces.
3. macOS: Seatbelt
Используется sandbox-exec с SBPL-профилем (Sandbox Policy Language). Профиль генерируется динамически на основе текущей политики:
- Базовые правила: deny write по умолчанию, allow read везде, allow file-write только для writable_roots.
- Сеть управляется флагом (allow network*) или отдельным network policy при network_access = false.
Seatbelt — Apple-нативный механизм, работает на уровне kernel.
4. Windows
Песочница Windows в ограниченном режиме. Изоляция ограничена:
- Запуск команд через AppContainer (когда доступно).
- Эскалация через /setup-default-sandbox для UAC.
Полноценная песочница на Windows пока не реализована.
5. Approvals: политики
Полный набор значений approval_policy (enum AskForApproval): untrusted | on-request | on-failure | granular | never. Значение по умолчанию — on-request.
approval_policy = "on-request"
untrusted
Спрашивает перед каждой командой, которая может писать на диск или в сеть. Пользователь видит точную команду и может отклонить.
on-request (по умолчанию, рекомендуется)
Агент сам решает, когда запросить подтверждение (например, для записи вне рабочей директории или выхода в сеть). Запрос показывается реальным диалогом-списком:
Would you like to run the following command? › 1. Yes, proceed (y) 2. Yes, and don't ask again for commands that start with `<prefix>` (p) 3. No, and tell AstraCode what to do differently (esc)
Клавиши настраиваются в /keymap. Варианта «редактировать команду» нет.
on-failure (устаревшая)
Команды выполняются в sandbox без вопросов; подтверждение запрашивается только если sandbox заблокировал операцию. Помечена в коде как DEPRECATED — для интерактивной работы используйте on-request, для неинтерактивной — never.
granular
Гранулированная политика подтверждений по типам действий.
never
Никогда не спрашивает. Все команды выполняются с правами, доступными в текущей политике. Используется, когда вы полностью доверяете агенту и проекту.
6. Approvals reviewer
approvals_reviewer = "user" # user | auto_review | guardian_subagent
Допустимые значения: user (по умолчанию), auto_review и guardian_subagent. Значения auto_review и guardian_subagent — синонимы (guardian_subagent — устаревший псевдоним, принимается для совместимости); оба включают один и тот же режим.
auto_review — использует второй LLM (или ту же модель) как ревьюера решений. Он смотрит контекст команды и одобряет/отклоняет автоматически, поднимая на пользователя только сомнительные.
Полезно для долгих сессий, чтобы не сидеть на approvals-диалогах. Стоит учитывать стоимость токенов.
7. /setup-default-sandbox
Команда /setup-default-sandbox (Windows):
- Запрашивает административные права (UAC на Windows).
- Создаёт расширенную песочницу с большим количеством разрешений.
- Логируется в audit-журнал.
8. /sandbox-add-read-dir
/sandbox-add-read-dir /opt/proprietary-data
Добавляет абсолютный путь в read-allowed список для текущей сессии. Не сохраняется в config. Полезно если AstraCode не может прочитать нужный каталог из-за политики.
9. Shell-escalation
На Unix-системах используется протокол shell escalation для контроля exec() вызовов внутри sandbox:
- AstraCode запускает патченный shell (
bash/zsh) с подмененной библиотекой черезLD_PRELOAD. - Библиотека перехватывает
execve()и отправляетEscalateRequestчерез unix-сокет ($ASTRACODE_ESCALATE_SOCKET). - Sandboxing-сервер AstraCode решает:
- Run — выполнить в текущем sandboxed контексте.
- Escalate — выполнить в привилегированном контексте сервера (например, для
sudo). - Deny — заблокировать.
Это позволяет иметь гранулярный контроль над вложенными командами в shell-скриптах без отключения sandbox.
См. крейт shell-escalation/.
10. Секреты: age + scrypt + OS keyring
Хранилище
Все секреты лежат в ~/.astracode/secrets/local.age — это JSON-сериализованный BTreeMap<String, Secret>, зашифрованный через age с scrypt KDF.
Мастер-ключ
Случайно сгенерированный 32-байтовый ключ:
- Кодируется в base64.
- Хранится в OS keyring под:
- service = "astracode"
- account = SHA256(canonical($ASTRACODE_HOME)) (первые 16 hex-символов)
Account-derivation зависит только от пути к ASTRACODE_HOME — не от версии бинарника. Поэтому обновление AstraCode не ломает доступ к секретам.
Запасной вариант
Если OS keyring недоступен (сервер без графического окружения, без DBus и т.п.):
- Ключ пишется в ~/.astracode/secrets/local.key (права 0o600).
- Этот fallback менее безопасен (ключ на диске рядом с шифротекстом).
Область действия
Секреты делятся на: - Global — доступны во всех сессиях (например, API-ключ OpenAI). - Environment — привязаны к git-репо или cwd (например, тестовые токены для конкретного проекта).
Scope определяется при добавлении секрета.
Восстановление секретов
Если Failed to decrypt secrets file:
- Проверьте, не сменился ли $ASTRACODE_HOME.
- Проверьте, не очищали ли OS keyring (например, переустановка GNOME Keyring).
- В худшем случае — удалите файл:
bash
rm ~/.astracode/secrets/local.age
Затем заново добавьте секреты через /model → ввод API-ключа.
11. Что попадает в секреты
- API-ключи провайдеров моделей (OpenAI, Anthropic, custom).
- OAuth-токены для MCP-серверов (по умолчанию).
- Bearer-токены для HTTP-MCP.
- Прочие именованные credentials, добавленные через скиллы или плагины.
API-ключи никогда не сохраняются в config.toml plaintext.
12. shell-environment-policy
Фильтрация переменных окружения, видимых командам, запускаемым агентом:
[shell_environment_policy] inherit = "minimal" # all | minimal | none allow = ["PATH", "HOME", "USER", "LANG", "TERM"] deny = ["SECRET_*", "AWS_*", "*_API_KEY", "GITHUB_TOKEN"]
inherit = "minimal" оставляет только базовые переменные. deny — паттерны (glob), которые блокируются даже если попали в allow.
Защита от случайной утечки секретов из родительской shell.
13. Журнал аудита
Всё, что требовало approval или эскалации, логируется:
~/.astracode/log/astracode-tui.log
Записи помечены префиксом audit:::
audit::approval granted tool=local_shell cmd="rm tmp.txt" reason="user_approved" audit::escalation requested cmd="sudo systemctl restart x" → denied
14. Модель угроз
Чему AstraCode противостоит:
- Случайным деструктивным командам от модели (rm -rf, перезапись файлов).
- Утечке API-ключей через child-процессы.
- Чтению/записи за пределами проекта без подтверждения.
- Сетевым запросам в режиме network_access = false.
Чему НЕ противостоит:
- Сознательно вредоносной модели с задержкой по времени (sleeper).
- Эксплойтам в самом bwrap/seatbelt (хотя они активно патчятся).
- Атакам по сторонним каналам (timing, memory disclosure).
- Социальной инженерии (пользователь сам жмёт Allow always).
Sandbox — это defense in depth, а не абсолютная защита. Для production-окружений запускайте AstraCode на изолированной машине или в контейнере.
15. Контроль лицензии
Дополнительный gate перед запуском TUI: бинарь требует валидный ed25519-подписанный токен в ~/.astracode/license_state.json (с HMAC-защитой против ручной правки) или OS keyring записи.
Краткая модель:
- Public key зашит в бинаре (license/src/keys.rs::PUBLIC_KEYS), приватный — offline у вендора.
- Token несёт Claims { lid, kid, iat, nbf, ver, license } где license = Trial { days } или Term { exp }.
- Активация (через astracode license activate --file … или drop в ~/.astracode/license.key) проверяет подпись, записывает ActivationRecord в keyring/файл, отслеживает activated_at (анкор для триалов) и last_seen (high-water mark против clock-rollback).
- При запуске enforce() сверяет подпись, MAC, дату-not-before, дату-expiry и rollback.
Полные технические детали — в docs/24-license.
Acknowledged offline limits (намеренные):
- Trial-reset в Docker / чистой VM (machine-id меняется → fallback integrity-key другой → ключ активируется как «новый»).
- Recompilation с заменёнными PUBLIC_KEYS (атакующий собирает свой бинарь со своими ключами).
- Полная wipe keyring + state — даёт переактивировать существующий ключ.
Для closed-loop защиты нужно online activation server — выходит за рамки текущей реализации.
16. Файлы кода
- Sandbox:
sandboxing/,linux-sandbox/,windows-sandbox-rs/ - Seccomp:
linux-sandbox/src/seccomp.rs - Bwrap:
linux-sandbox/src/bwrap.rs - Landlock:
linux-sandbox/src/landlock.rs - Process hardening:
process-hardening/ - Shell escalation:
shell-escalation/ - Exec policy:
execpolicy/ - Secrets:
secrets/,keyring-store/ - Approvals UI:
tui/src/chatwidget/approvals.rs