Обзор архитектуры
Почему принудительное применение политик реализовано локально и в виде компилируемого кода
Фундаментальное архитектурное решение состоит в том, что агент рабочей станции — это механизм принятия решений, а контрольная плоскость — распространитель политик и приёмник аудита.
Перед тем как остановиться на этой модели, были рассмотрены и отклонены три альтернативы:
| Альтернатива | Почему отклонена |
|---|---|
| Принятие решений на стороне сервера (агент спрашивает у центрального сервера «разрешить или заблокировать?» по каждому событию) | Добавляет полный сетевой цикл запроса и ответа в критический путь применения политики, ослабляет гарантию запрета при сбое сети и ставит задержку и доступность в зависимость от контрольной плоскости, а не рабочей станции. |
| Тонкая локальная обёртка + тяжёлая облачная логика (агент только пересылает данные, всё обнаружение происходит на стороне сервера) | Нарушает границу доверия, ради которой продукт разворачивается в инфраструктуре организации, и по определению не позволяет скрыть исходные данные: для оценки они должны были бы покидать рабочую станцию. |
| Полностью облачная SaaS-контрольная плоскость | Несовместима с регулируемым развёртыванием в инфраструктуре организации или в изолированном от внешней сети контуре как штатным, а не аварийным режимом. |
Принятая модель: агент рабочей станции оценивает каждое решение относительно сохранённого на рабочей станции подписанного снимка политики**. Роль контрольной плоскости — формировать, подписывать и распространять этот снимок, а также постфакту получать журнал аудита с удалёнными чувствительными данными. Это зафиксировано как первое архитектурное решение проекта и рассматривается как практически неизменяемое — изменение требует новой записи об архитектурном решении.
Граница доверия
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "-apple-system, Segoe UI, Helvetica, Arial, sans-serif", "primaryColor": "#eef2f7", "primaryTextColor": "#0b0b0b", "primaryBorderColor": "#5b6b7c", "lineColor": "#5b6b7c", "secondaryColor": "#eef4ff", "tertiaryColor": "#f4f3f0", "clusterBkg": "#f9f9f7", "clusterBorder": "#c3c2b7", "edgeLabelBackground": "#fcfcfb", "actorBkg": "#eef2f7", "actorBorder": "#5b6b7c", "actorTextColor": "#0b0b0b", "actorLineColor": "#5b6b7c", "signalColor": "#52514e", "signalTextColor": "#0b0b0b", "labelBoxBkgColor": "#eef4ff", "labelBoxBorderColor": "#5b6b7c", "labelTextColor": "#0b0b0b", "loopTextColor": "#0b0b0b", "noteBkgColor": "#fdf3d9", "noteBorderColor": "#c98500", "noteTextColor": "#3d2f00", "activationBorderColor": "#5b6b7c", "activationBkgColor": "#eef4ff", "sequenceNumberColor": "#ffffff"}}}%%
flowchart TB
subgraph Workstation["Рабочая станция разработчика — граница доверия A"]
direction TB
Shell["Перехват командной оболочки<br/>(PTY: bash/zsh, PowerShell, cmd.exe)"]
MCP["Посредник MCP / JSON-RPC"]
Clip["Монитор буфера обмена"]
Repo["Локальная проверка репозиториев"]
Kernel["Посредничество в доступе к файлам на уровне ядра<br/>(fanotify / Endpoint Security)"]
Detect["Механизм обнаружения<br/>(регулярные выражения + энтропия + контрольные суммы + NER)"]
Mask["Потоковое маскирование"]
Policy["Механизм применения политик<br/>(подписанный снимок, запрет при сбое)"]
Shell --> Detect
MCP --> Detect
Clip --> Detect
Repo --> Detect
Kernel --> Policy
Detect --> Mask
Policy --> Shell
Policy --> MCP
Policy --> Clip
end
subgraph ControlPlane["Локальная контрольная плоскость — граница доверия B"]
direction TB
PolicyAPI["Создание и подписание политик"]
EventAPI["Приём событий и сигналов состояния"]
AdminUI["Административный интерфейс"]
PG[("PostgreSQL")]
IdP["OIDC / совместимо с Keycloak"]
PolicyAPI --> PG
EventAPI --> PG
AdminUI --> PolicyAPI
AdminUI --> EventAPI
AdminUI --> IdP
end
Policy -. "получает подписанный снимок" .-> PolicyAPI
Mask -. "только обезличенные события\n(хеши, счётчики, классификации)" .-> EventAPI
Решение принимается и применяется внутри границы доверия A. Ничто внутри границы B не может навязать рабочей станции результат быстрее, чем следующая загрузка подписанной политики, и ничто, пересекающее путь из A в B, не переносит необработанное чувствительное содержимое — точную гарантию очистки см. в разделе Телеметрия без раскрытия данных.
Далее: Защита на уровне ядра.