# Модель безопасности ## Защищаемые данные - SSH, WireGuard, device и agent identities; - topology, внутренние адреса, метрики и состояния Links; - команды, терминальные сессии и аудит; - права пользователей и AI-агентов. ## Границы доверия Windows client, Hub и каждый Node считаются отдельными субъектами. Компрометация одного Node не должна выдавать ключи других узлов или право создавать новые Links. Hub хранит только публичные WireGuard-ключи Node. Приватный ключ Node генерируется локально, не включается в enrollment token и не записывается на Hub. ## SSH monitoring MVP Windows-клиент использует отдельный Ed25519-ключ только для forced-command. Этот ключ не используется для интерактивного терминала или AI-агента. Первый host key требует явного подтверждения fingerprint; последующие подключения проверяют сохранённый `known_hosts`. Приватный ключ клиента защищается Windows DPAPI и доступом текущего пользователя. Профили серверов не содержат паролей. ## Регистрация Node 1. На Hub создаётся случайный enrollment token со сроком жизни не более 10 минут. 2. Node локально генерирует WireGuard-ключ. 3. Node предъявляет token и публичный ключ по защищённому каналу. 4. Hub атомарно помечает token использованным, регистрирует адрес и возвращает подтверждение, которое связывает token, публичный ключ и все параметры конфигурации. 5. Повторное использование, просроченный token и смена публичного ключа отклоняются. До появления mTLS enrollment выполняется через отдельную ограниченную SSH-команду. Token не должен содержать приватный WireGuard-ключ. ## Operator identity Windows-клиента Windows-клиент получает отдельный код `SMMDEV1`, показывает URL и SHA-256 fingerprint Control CA и продолжает регистрацию только после явного подтверждения пользователя. Приватный operator key создаётся локально, хранится в DPAPI current-user scope и не используется как SSH monitoring, terminal или Agent identity. Сертификат `Agent` разрешает только heartbeat собственного `node_id`. Только сертификат с ролью `Operator` может читать общий inventory, изменять Links и подписываться на event stream. Сертификат `Automation` выдаётся по отдельному одноразовому token, привязан к одному source Node и разрешает только чтение его эффективных Link-grants без `reason`, общего inventory и чужих Links. Control service вызывает от root только отдельный wrapper с командами `link-connect` и `link-disconnect`; другие Hub-команды через него запрещены. При перерегистрации Node Control Hub в одной SQLite-транзакции помечает старый сертификат `Revoked`, погашает ранее выданные enrollment tokens и переводит все связанные Links в желаемое состояние `Disabled`. Только после этого ограниченный firewall wrapper удаляет фактические правила. Новый token живёт 10 минут, а повтор запроса с тем же idempotency key не создаёт второй token и не повторяет firewall-операции. Windows-клиент требует отдельного подтверждения и не публикует token в event stream или аудит. ## Авторизация Links - мониторинг read-only отделён от управления; - Link всегда содержит source, destination, CIDR, протокол и порт; - пустой список портов не означает разрешение всех портов; - automation identity не наследует интерактивные права владельца; - команды имеют TTL, nonce/idempotency key и версию политики; - Hub проверяет имена и параметры повторно, независимо от проверки desktop client. ## Аудит Записываются регистрация и удаление узла, изменение прав, создание, включение, истечение и отключение Link, а также ошибки применения. Секреты, приватные ключи и полный ввод терминала не журналируются. Для первого MVP используется append-only JSONL с ограниченными правами и ротацией. После появления control service аудит переносится в SQLite с возможностью внешнего экспорта. ## Kill switch Отключение Link должно: 1. немедленно удалить разрешающее правило на Hub; 2. записать желаемое состояние `Disabled` до отправки дополнительных команд; 3. запретить автоматическое восстановление после reboot/reconnect долговечным SQLite-marker, который снимается только после подтверждения firewall; 4. получить подтверждение применённой версии политики; 5. показывать `Partial`, если подтверждение одного из узлов отсутствует; 6. сохранить обязательную операцию для временно недоступного Node. ## Provisioning и VPN Provisioning расширяет существующую модель ролей, но не предоставляет удалённый root shell: - mutation создаёт только Operator и только для явно выбранного `node_id`; - Agent получает задания исключительно своего Node; - Automation identity не управляет ОС, пользователями, firewall или VPN; - root helper принимает фиксированный action id и JSON строгой versioned schema через локальный Unix socket; - helper повторно валидирует параметры, использует фиксированный `PATH` и отклоняет shell text, неизвестные поля, произвольные paths и symlinks; - опасное задание имеет TTL, idempotency key, audit reason, отдельное подтверждение, verification и rollback; - одновременно на Node не выполняются несовместимые опасные задания; - неопределённый результат после disconnect получает `NeedsReconciliation`; - повторная регистрация Node инвалидирует незавершённые опасные задания; - VPN subscription secret шифруется на публичный ключ конкретного Node, а Control хранит только ciphertext и маскированные metadata; - локальная emergency recovery может отключить managed VPN и восстановить SSH/firewall без Control Hub, но не запускает произвольную команду. Подробный контракт приведён в [ТЗ Provisioning и Xray VPN](provisioning-vpn-requirements.md). ## Недоверенные исполнители на Node Статус: инвариант для будущих модулей, реализация не начата. Любой компонент, исполняющий на Node внешний код — прежде всего KAgent Worker, — считается недоверенным субъектом и изолируется от control plane, а не только от внешней сети. Сборка репозитория запускает его build-скрипты, поэтому «ограниченный набор возможностей» не означает ограниченного исполнения. Обязательные условия: - отдельный системный пользователь без sudo, отдельные каталоги и cgroup; - нет доступа к сокету provisioning-helper и запрет членства в группе Agent; - нет доступа к `agent.pfx`, `control-ca.crt`, `agent.env`, состоянию mesh и каталогу rollback; - нет сетевого доступа к Control API; - исполнение в контейнере с read-only rootfs, seccomp, AppArmor и сброшенными capabilities; - системные лимиты дополняют изоляцию, но не заменяют её; - задачный Link не может иметь destination Hub или другой недоверенный исполнитель. Компрометация такого исполнителя не должна давать управления Node, доступа к другим Node или возможности создать Link. Подробности: [интеграция с KAgent](integration-kagent.md). ## Публичный интерфейс Статус: решение не принято, работы не начаты. Текущая модель держится на трёх утверждениях: у Node нет публичного входящего API, Control доступен только по mTLS, порт Control не открывается без ограничений firewall. Веб-интерфейс с аутентификацией по паролю вводит браузерный surface на Hub и вторую систему идентичности рядом с сертификатами устройств. До начала работ над веб-интерфейсом требуется зафиксировать здесь: - отдельный listener и порт, отношение к цепочке сертификатов Control; - как веб-сессии соотносятся с mTLS-идентичностями в модели ролей; - перечень операций, недоступных веб-сессии в принципе и требующих mTLS-идентичности — как минимум изменение firewall, ротация CA, удаление Node и экспорт секретов; - привязка сессии к устройству, защита от CSRF, ограничение частоты и повторная аутентификация для операций повышенного риска. ## Невыдаваемые возможности Часть возможностей не является настройкой и не может быть выдана никакой внешней идентичности: исполнение произвольных команд от root, ротация Control CA, чтение содержимого секретов, отключение аудита, удаление Node. Требование означает отсутствие соответствующего кода в пути внешней идентичности, а не значение по умолчанию. Прецедент: сертификат `Automation` физически не может изменять Links. Та же строгость распространяется на все последующие внешние интеграции. ## Не входит в первый MVP - выполнение произвольных root-команд; - хранение пользовательских приватных SSH-ключей на Hub; - автоматическое объединение всех серверов в flat network; - публичный входящий API на Node; - собственная криптография вместо SSH, TLS и WireGuard; - автоматический failover между несколькими Hub.