Когда правила безопасности живут в документах, их игнорируют
Команда безопасности неделями пишет политику сканирования образов контейнеров. Рассылает её по email, объявляет на общем собрании и сохраняет в корпоративной вики. Через три месяца кто-то проверяет production-пайплайн и обнаруживает, что сканирование так и не включено. Конфигурация отсутствовала в одном проекте, и никто этого не заметил.
Это не история о злом умысле. Это история о том, как правила ломаются, когда живут вне пайплайна.
Проблема правил в виде документов
Письменные политики имеют фундаментальную слабость: они зависят от людей, которые должны их прочитать, запомнить и правильно применить. Каждая команда интерпретирует одно и то же правило по-своему. У каждого проекта свои особенности конфигурации. Когда правило меняется, кто-то должен вручную обновить все места, где оно применяется, а кто-то другой — проверить, что обновление действительно произошло.
Результат предсказуем. Одни команды следуют правилам. Другие следуют немного другой версии. Третьи забывают полностью. И никто не знает, какая ситуация имеет место, пока что-то не пойдёт не так.
Разница между этими двумя подходами становится очевидной, если изобразить поток:
Это не проблема людей. Это проблема доставки. Правила не являются частью системы, которая доставляет программное обеспечение. Они существуют вне её, как текст, требующий человеческого перевода в действие.
Пишем правила как код
Policy as code меняет модель доставки правил. Вместо написания политик в документах вы пишете их в формате, который могут читать машины, храните их в репозитории и выполняете как часть пайплайна. Тот же рабочий процесс, который обрабатывает код приложения, теперь обрабатывает ваши правила безопасности и соответствия.
Формат может быть разным. Одни команды используют Rego от Open Policy Agent. Другие — YAML с определённой схемой. Третьи — встроенные фреймворки политик из существующих инструментов сканирования. Язык имеет меньшее значение, чем принцип: правила пишутся, версионируются, рецензируются и выполняются автоматически.
Рассмотрим простое правило: контейнеры не должны запускаться от root. В policy as code это становится чётким утверждением, которое может оценить движок политик. Пайплайн запускает движок для каждого образа контейнера перед развёртыванием. Если образ запускается от root, пайплайн останавливается. Если правило нужно изменить, кто-то редактирует файл политики, открывает pull request и ждёт ревью. Изменение проходит тот же процесс, что и любое изменение кода.
Что меняется, когда правила становятся кодом
Первое преимущество — консистентность. Одно и то же правило выполняется для каждого проекта, каждого пайплайна, каждого развёртывания. Нет разрыва из-за того, что кто-то забыл включить сканирование или две команды настроили один и тот же инструмент по-разному. Когда добавляется новое правило, каждый пайплайн подхватывает его автоматически.
Второе преимущество — тестируемость. До policy as code как вы узнавали, что новое правило корректно? Вы могли протестировать его в production-пайплайне, что рискованно. Или пропустить тестирование и надеяться на лучшее. С policy as code вы пишете тесты для своих правил. Вы создаёте тестовый случай, где контейнер с root-пользователем не проходит политику, и другой, где контейнер без root проходит. Эти тесты выполняются в CI, как модульные тесты. Если кто-то изменит правило и сломает логику, тесты поймают это до того, как правило попадёт в production.
Третье преимущество — аудируемость. Каждое изменение правила фиксируется в системе контроля версий. Вы можете увидеть, кто что изменил, когда и почему. Вы можете откатить неудачное изменение правила так же, как откатываете неудачное изменение кода. Когда аудитор спрашивает, запускаются ли ваши контейнеры от root, вы указываете на файл политики и логи пайплайна, а не на документ, который может быть устаревшим.
Вам не нужно писать всё с нуля
Распространённое заблуждение состоит в том, что policy as code означает написание каждого правила самостоятельно. На практике большинство правил берётся из существующих фреймворков. Инструменты безопасности поставляются с политиками для эталонов CIS, нормативных фреймворков и общих шаблонов безопасности. Вы включаете те, которые применимы к вашей организации, и настраиваете пороговые значения в соответствии с вашей толерантностью к риску.
То, что вы пишете с нуля, обычно специфично для вашей организации. Возможно, ваша компания запрещает развёртывание в определённых облачных регионах. Возможно, каждый ресурс должен иметь определённый набор меток. Возможно, production-развёртывания требуют второй подписи. Это те правила, которые не покрываются существующими фреймворками, и именно они выигрывают больше всего от написания в виде кода.
Практический сдвиг
Policy as code меняет отношения между командами безопасности и инженерными командами. Безопасность больше не перебрасывает правила через стену и не надеется, что они будут реализованы. Безопасность пишет правила как код, отправляет их через тот же процесс ревью, что и код приложения, и видит результаты в каждом запуске пайплайна.
Инженерные команды больше не гадают, следуют ли они правилам. Пайплайн сообщает им об этом немедленно. Если изменение нарушает политику, сборка падает с чётким сообщением. Команда исправляет проблему до того, как она попадёт в production, а не после того, как аудит обнаружит её шесть месяцев спустя.
Краткий чеклист для начала
- Выберите одно правило, которое задокументировано, но часто нарушается.
- Напишите это правило как код, используя фреймворк политик вашего существующего инструмента безопасности.
- Добавьте проверку политики в ваш CI-пайплайн.
- Напишите тест, который доказывает, что правило ловит нарушения.
- Напишите другой тест, который доказывает, что правило пропускает соответствующие изменения.
- Удалите старый документ и укажите людям на файл политики вместо него.
Начните с одного правила. Докажите, что рабочий процесс работает. Затем расширяйтесь.
Вывод
Правила, которые живут в документах, — это правила, которые игнорируют. Правила, которые живут в пайплайне, — это правила, которые выполняются. Policy as code — это не про написание большего количества правил. Это про то, чтобы заставить уже существующие правила действительно работать, каждый раз, для каждого изменения, не полагаясь на то, что кто-то вспомнит прочитать email.