Механизм применения политик и цепочка доверия
Политика — корень доверия для каждого решения о применении правил: то, как правило создаётся, как оно подписывается, как агент проверяет его перед тем как довериться ему, и как оно оценивается применительно к реальной команде или запросу.
Жизненный цикл
%%{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 LR
Author["Создание правила\n(административный интерфейс, без ручного редактирования JSON)"] --> Validate["Проверка черновика\n(компиляция регулярного выражения,\nсогласованность границ длины,\nналичие обязательных полей)"]
Validate --> Simulate["Проверка на\nпримере команды"]
Simulate --> Resolve["Разрешение наследования\n(в глубину, с фиксацией\nисточников/переопределений)"]
Resolve --> Sign["Подпись при публикации\n(Ed25519, ID ключа, отпечаток)"]
Sign --> Distribute["Распространение подписанного снимка"]
Distribute --> Verify["Агент проверяет\nперед доверием"]
Verify --> Evaluate["Оценка применительно к\nреальным командам/запросам"]
Sign -.откат.-> Author
Создание правил
Офицер безопасности формирует правила — условия совпадения, действие, уровень серьёзности, код причины, селекторы командной оболочки, область действия и исключения — через административный интерфейс. Черновики проверяются перед публикацией: некомпилируемое регулярное выражение, несогласованные границы длины или отсутствующее обязательное поле отклоняются на этом этапе. Черновик можно симулировать на примере командной строки перед публикацией — результатом будет действие и идентификатор сработавшего правила.
Наследование разрешается в глубину на момент публикации: источники правил и переопределения фиксируются внутри самого подписанного блока композиции, а отсутствующая родительская политика или цикл наследования отклоняются.
Подпись и проверка целостности
Каждый распространяемый снимок политики — это пакет, подписанный Ed25519, и агент проверяет его в строгой упорядоченной цепочке, прежде чем считать активным:
%%{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
S1["1. Проверка версии схемы"] --> S2["2. Проверка правильности структуры"]
S2 --> S3["3. Отпечаток содержимого\n(SHA-256 канонического представления)"]
S3 --> S4["4. Проверка подписи Ed25519\n(только по явно заданному набору доверенных ключей)"]
S4 --> S5["5. Проверка срока действия"]
S5 --> Active["Снимок становится активным"]
S1 -.любой сбой.-> Fail["режим выполнения strict_fallback\n+ событие policy_integrity_failure\n(severity: high)"]
S2 -.любой сбой.-> Fail
S3 -.любой сбой.-> Fail
S4 -.любой сбой.-> Fail
S5 -.любой сбой.-> Fail
style Fail fill:#fbe4e4,stroke:#d03b3b,color:#5c1616
Эти свойства закрывают типичные ловушки систем на основе подписей:
- Доверие ограничено явно настроенным набором ключей. Неявного якоря доверия не существует. Пустая конфигурация доверия означает пустой набор доверенных ключей, а значит — сбой проверки для каждого снимка: сценарий «доверие ещё никто не настроил» закрыт.
- Встроенный ключ подписи для разработки никогда не считается доверенным во время выполнения, даже если ошибочная конфигурация явно включает его в список — это жёстко закодированный отказ.
- Управляемое хранилище доверенных ключей должно быть обычным файлом, а не символической
ссылкой; оно должно принадлежать
rootи не давать права записи группе или всем остальным. Другой владелец требует явного отказа от защиты, доступного только в тестовом режиме. - Защита от атак повторного воспроизведения: снимок отклоняется, если его
policy_versionниже самой высокой уже принятой версии; идентичная пара версия+отпечаток принимается идемпотентно (её безопасно применить повторно). Максимально достигнутое значение версии хранится в локальном состоянии, принадлежащем root. - Каждый распространяемый снимок должен содержать поле
expires_at. - Контрольная плоскость по умолчанию использует рабочий профиль безопасности; профиль для разработки требует явной настройки и записывает предупреждение в журнал — это опция, которую нужно включить сознательно. Рабочий профиль дополнительно безоговорочно отклоняет идентификатор ключа подписи для разработки, байты закрытого ключа для разработки и файл ключа подписи, доступный на чтение группе.
- Канонизация для вычисления отпечатка/подписи — это повторная сериализация разобранной структуры.
Оценка
Правила в активном снимке оцениваются в порядке снимка — первое совпадение
побеждает. Если ничего не совпало, результатом является блокировка (block) с отдельным
кодом причины запрета при сбое — неявного правила «нет совпадения = разрешить» не существует.
- Измерения селектора (поверхность, командная оболочка, область действия, совпадение команды, требуемые находки) конъюнктивны между измерениями и дизъюнктивны внутри одного измерения: каждое заполненное измерение должно совпасть, но внутри одного измерения достаточно совпадения с любым из нескольких значений. Пустое измерение не накладывает ограничений. Сопоставление текста — регистронезависимое сопоставление подстроки, если измерение не задаёт регулярное выражение.
- Исключения подавляют сработавшее правило только если каждое заполненное измерение исключения совпадает с текущим контекстом — пустое исключение никогда не может случайно примениться ко всему.
- Неисправное регулярное выражение не прерывает оценку — направление отказа осознанно
выбирается в зависимости от типа правила: в правиле
blockилиmask_outputнекомпилируемый шаблон считается совпадением (запрет при сбое — лучше заблокировать лишнее, чем молча пропустить правило, которое даже нельзя проверить); в правилеallowилиwarnтот же неисправный шаблон просто не даёт совпадения (разрешение при сбое, но только в том смысле, что ни одно заявленное ограничение не было молча пропущено, посколькуallowиwarnизначально не заявляют о блокировке). - Каждый шаблон регулярного выражения компилируется не более одного раза на снимок — осознанная мера контроля затрат в критическом пути, поскольку оценка выполняется на каждой перехваченной команде.
Далее: Телеметрия без раскрытия данных и контрольная плоскость.