Короткий ответ
Нужно разделить политики по уровню строгости: небольшой набор hard-блокирующих правил только для однозначно недопустимых и дорого обходящихся рисков (публичный SSH/RDP, отключённое шифрование секретных данных), и более широкий набор warn-only/advisory правил, которые требуют явного подтверждения (например, обязательного объяснения в PR или approval второй командой) вместо автоматической блокировки; также необходим управляемый процесс исключений (exception process) с временным approved override и сроком действия, а не постоянные ручные обходы политики через отключение проверки целиком.
Как это работает подробнее
policy as code работает, анализируя план (JSON-вывод terraform show -json) или итоговые манифесты до их применения, и возвращает allow/deny на основе правил; жёсткая блокировка без пути легитимного исключения заставляет команды искать обходные пути (например, вручную редактировать ресурс после apply, что создаёт drift), поэтому важно не только писать правила, но и спроектировать процесс работы с их нарушениями.
Сравнение
- Компромисс. Чем шире список hard-блокирующих правил, тем выше гарантированный уровень безопасности, но тем больше трения с командами и тем выше риск, что команды начнут искать обходные пути (ручные правки после apply, параллельные неуправляемые ресурсы), что хуже с точки зрения общего риска, чем сам исходный edge-кейс. Узкий набор строгих правил плюс управляемый процесс исключений даёт более медленное, но устойчивое повышение зрелости, тогда как агрессивный подход быстрее формально закрывает риски, но создаёт скрытый технический долг в виде обходов. Решение должно учитывать требования compliance и реальную частоту легитимных edge-кейсов.
Пример кода
# пример: hard-block только для явно недопустимого риска
deny[msg] {
input.resource_type == "aws_security_group_rule"
input.cidr_blocks[_] == "0.0.0.0/0"
input.from_port <= 22
input.to_port >= 22
msg := "SSH не может быть открыт на 0.0.0.0/0"
}
# пример: advisory-правило, требующее подтверждения, а не блокировки
warn[msg] {
input.resource_type == "aws_db_instance"
not input.multi_az
msg := "БД без multi-AZ: подтвердите, что это осознанный выбор для этого окружения"
}Что использовать на практике
- Практика. метрика успеха такой системы — не количество заблокированных plan'ов, а соотношение реально предотвращённых инцидентов к количеству ложных блокировок легитимных кейсов; для этого полезно вести лог решений (allow/deny/override) и периодически пересматривать правила с участием команд-разработчиков, а не только силами платформенной/security-команды, чтобы правила отражали реальные ограничения бизнеса, а не только теоретические риски.
Подводные камни
- Ошибка. Не выполняйте изменение без проверки плана, резервной копии состояния и понятного способа отката; для production согласуйте окно работ и исключите параллельные операции.