0.4.11
09 · Техническая документация

09. Безопасность

Безопасность AstraCode строится на трёх независимых уровнях:

  1. Sandbox — изоляция выполнения команд от файловой системы и сети.
  2. Approvals — пользовательские разрешения на потенциально опасные операции.
  3. Secrets — криптографическая защита API-ключей и токенов.

1. Sandbox: три режима

read-only

Наиболее строгий. Процессы видят всю файловую систему read-only (включая проект), не могут писать никуда. Сеть отключена. Полезно для анализа кода без побочных эффектов.

workspace-write (рекомендуемый для разработки)

Среднеуровневый. Чтение FS неограничено. Запись разрешена только в writable_roots (по умолчанию — корень проекта и /tmp). Метаданные проекта (.git, .agents, .astracode) защищены от записи даже здесь — никакие команды не могут случайно поломать git-историю.

Сеть управляется отдельно:

toml
[sandbox_workspace_write]
writable_roots = ["/home/user/work/myproject"]
network_access = false
exclude_tmpdir_env_var = false   # true → не разрешать запись в $TMPDIR
exclude_slash_tmp = false         # true → не разрешать запись в /tmp

danger-full-access

Отключает sandbox полностью. Используется только для явно доверенных операций. Эскалация в этот режим требует подтверждения пользователя (через approvals).

В конфиге:

toml
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 (реализовано в linux-sandbox/src/lib.rs и linux-sandbox/src/linux_run_main.rs): - Блокирует setuid, setgid, capset (эскалация привилегий). - При выключенной сети (network_access = false) блокирует системные вызовы создания сокетов (кроме AF_UNIX для shell-escalation).

Landlock (legacy)

Альтернатива bwrap для систем без user namespaces (например, ограниченные контейнеры, WSL1 не поддерживается совсем). Включается флагом:

bash
astracode --enable use_legacy_landlock

Landlock — это in-kernel LSM, ограничивающий FS-доступ без namespaces. Флаг use_legacy_landlock помечен Stage::Deprecated — оставлен для совместимости со старыми конфигами.

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 sandbox в degraded mode. Изоляция ограничена: - Запуск команд через AppContainer (когда доступно). - Эскалация через /setup-default-sandbox для UAC.

Полноценный sandbox на Windows — TODO в roadmap.

5. Approvals: пять политик

AskForApproval (см. protocol/src/protocol.rs:961) имеет пять вариантов:

toml
approval_policy = "on-failure"

untrusted (UnlessTrusted)

Спрашивает перед каждой командой, которая может писать на диск или в сеть. Пользователь видит точную команду и может отклонить.

on-failure (OnFailure) — DEPRECATED

Команды выполняются в sandbox без вопросов. Если sandbox блокирует операцию (например, запись в .git), AstraCode показывает approval-диалог:

Tool wants to write to .git/config. Allow? [Allow once] [Allow always] [Deny]

Allow once — разрешить только этот вызов. Allow always — добавить путь в writable_roots.

Вариант помечен DEPRECATED — для интерактивных запусков рекомендуется on-request, для неинтерактивных — never.

on-request (OnRequest, по умолчанию)

Модель сама решает, когда спрашивать пользователя об approval.

granular (Granular)

Тонкая настройка отдельных approval-потоков через GranularApprovalConfig (sandbox_approval, rules, skill_approval, request_permissions, mcp_elicitations). Когда поле true — запросы в этой категории разрешаются; когда false — автоматически отклоняются вместо показа пользователю.

never (Never)

Никогда не спрашивает. Все команды выполняются с правами, доступными в текущей политике. Используется, когда вы полностью доверяете агенту и проекту.

6. Approvals reviewer

toml
approvals_reviewer = "user"   # user | auto

auto — использует второй LLM (или ту же модель) как ревьюера решений. Он смотрит контекст команды и одобряет/отклоняет автоматически, поднимая на пользователя только сомнительные.

Полезно для долгих сессий, чтобы не сидеть на approvals-диалогах. Стоит учитывать стоимость токенов.

7. /setup-default-sandbox

Команда /setup-default-sandbox на Windows: - Запрашивает административные права (UAC на Windows). - Создаёт расширенную песочницу с большим количеством разрешений. - Логируется в audit-журнал.

8. /sandbox-add-read-dir

Команда доступна только на Windows (VisibilityRule::WindowsOnly):

text
/sandbox-add-read-dir C:\proprietary-data

Добавляет абсолютный путь в read-allowed список для текущей сессии. Не сохраняется в config. Полезно если AstraCode не может прочитать нужный каталог из-за политики.

9. Shell-escalation

На Unix-системах используется протокол shell escalation для контроля exec() вызовов внутри sandbox:

  1. AstraCode запускает патченный shell (bash/zsh) с подмененной библиотекой через LD_PRELOAD.
  2. Библиотека перехватывает execve() и отправляет EscalateRequest через unix-сокет ($ASTRACODE_ESCALATE_SOCKET).
  3. Sandboxing-сервер AstraCode решает: - Run — выполнить в текущем sandboxed контексте. - Escalate — выполнить в привилегированном контексте сервера (например, для sudo). - Deny — заблокировать.

Это позволяет иметь гранулярный контроль над вложенными командами в shell-скриптах без отключения sandbox.

См. крейт shell-escalation/.

10. Секреты: age + scrypt

Хранилище

Все секреты лежат в ~/.astracode/secrets/local.age — это JSON-сериализованный BTreeMap<String, String> (имя секрета → строковое значение), зашифрованный через age с scrypt KDF. Структура файла — SecretsFile { version, secrets: BTreeMap<String, String> } (см. secrets/src/local.rs:50). Отдельных полей scope/metadata у секрета нет.

Мастер-ключ

Случайно сгенерированный 32-байтовый ключ кодируется в base64. Место хранения выбирает ASTRACODE_PROVIDER_SECRETS_KEY_STORAGE:

  • filesecrets/local.key с правами только для владельца;
  • keyring — обязательный OS credential store;
  • auto — предпочесть keyring и fallback'нуть в файл.

Default на macOS — file, потому что ad-hoc signed builds не гарантируют стабильный доступ к Keychain. На остальных платформах default — auto.

В keyring используются service astracode и account secrets|<short-hash>, где hash зависит от canonical $ASTRACODE_HOME, а не от версии бинарника. При file storage рядом с local.age существует local.key; оба файла необходимы для восстановления.

Scope

Секреты делятся на: - Global — доступны во всех сессиях (например, API-ключ OpenAI). - Environment — привязаны к git-репо или cwd (например, тестовые токены для конкретного проекта).

Scope определяется при добавлении секрета.

Восстановление секретов

Если Failed to decrypt secrets file: - Проверьте, не сменился ли $ASTRACODE_HOME. - Проверьте значение ASTRACODE_PROVIDER_SECRETS_KEY_STORAGE и наличие secrets/local.key либо записи в OS keyring. - Перед сбросом остановите AstraCode и переместите vault в резервную директорию: bash mkdir -p ~/.astracode/secrets-recovery-backup mv ~/.astracode/secrets/local.age ~/.astracode/secrets-recovery-backup/ test ! -f ~/.astracode/secrets/local.key || \ mv ~/.astracode/secrets/local.key ~/.astracode/secrets-recovery-backup/ Затем заново добавьте секреты через /model. Без исходного ключа старый local.age расшифровать нельзя; резервная копия сохраняет шанс восстановить его позднее.

11. Что попадает в секреты

  • API-ключи провайдеров моделей (OpenAI, Anthropic, custom).
  • OAuth-токены для MCP-серверов (по умолчанию).
  • Bearer-токены для HTTP-MCP.
  • Прочие именованные credentials, добавленные через скиллы или плагины.

API-ключи никогда не сохраняются в config.toml plaintext.

12. shell-environment-policy

Фильтрация переменных окружения, видимых командам, запускаемым агентом (см. config/src/types.rs:849, ShellEnvironmentPolicyToml):

toml
[shell_environment_policy]
inherit = "core"       # all | core | none (по умолчанию all)
set = { RUST_LOG = "debug" }     # явно задать переменные
include_only = ["PATH", "HOME", "USER", "LANG", "TERM"]   # regex-паттерны: оставить только совпадающие
exclude = ["SECRET_.*", "AWS_.*", ".*_API_KEY", "GITHUB_TOKEN"]  # regex-паттерны: заблокировать
ignore_default_excludes = true   # true → не применять встроенный список исключений

Поля allow/deny не существуют — используются set (явно задать), include_only (regex оставить) и exclude (regex заблокировать).

inherit: - all (по умолчанию) — наследовать всё окружение родительского процесса. - core — только платформенные «core» переменные (на UNIX: HOME, LOGNAME, PATH, SHELL, USER и т.п.). - none — не наследовать ничего.

exclude — regex-паттерны, которые блокируются даже если попали в include_only. Защита от случайной утечки секретов из родительской shell.

13. Audit log

Всё, что требовало approval или эскалации, логируется:

text
~/.astracode/log/astracode-tui.log

Записи approval/эскалации пишутся стандартными tracing-событиями (без специального audit::-префикса); для поиска используйте фильтр по модулю, например:

text
RUST_LOG=astracode_core::tools=debug,astracode_shell_escalation=debug

и ищите в логе события об одобренных/отклонённых операциях.

14. Threat model

Чему AstraCode противостоит: - Случайным деструктивным командам от модели (rm -rf, перезапись файлов). - Утечке API-ключей через child-процессы. - Чтению/записи за пределами проекта без подтверждения. - Сетевым запросам в режиме network_access = false.

Чему НЕ противостоит: - Сознательно вредоносной модели с задержкой по времени (sleeper). - Эксплойтам в самом bwrap/seatbelt (хотя они активно патчятся). - Атакам по сторонним каналам (timing, memory disclosure). - Социальной инженерии (пользователь сам жмёт Allow always).

Sandbox — это defense in depth, а не абсолютная защита. Для production-окружений запускайте AstraCode на изолированной машине или в контейнере.

15. Файлы кода

  • Sandbox: sandboxing/, linux-sandbox/, windows-sandbox-rs/
  • Seccomp: linux-sandbox/src/lib.rs, linux-sandbox/src/linux_run_main.rs (отдельного 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/bottom_pane/approval_overlay.rs