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

Landlock (legacy)

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

toml
[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.

toml
approval_policy = "on-request"

untrusted

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

on-request (по умолчанию, рекомендуется)

Агент сам решает, когда запросить подтверждение (например, для записи вне рабочей директории или выхода в сеть). Запрос показывается реальным диалогом-списком:

text
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

toml
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

text
/sandbox-add-read-dir /opt/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 + 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

Фильтрация переменных окружения, видимых командам, запускаемым агентом:

toml
[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 или эскалации, логируется:

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

Записи помечены префиксом audit:::

text
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