Платформенная инженерия Безопасность по умолчанию: секреты, доступы, соответствие требованиям
0%

Безопасность по умолчанию: секреты, доступы, соответствие требованиям

Безопасность по умолчанию: секреты, доступы, соответствие требованиям

Платформенная команда получила задачу от службы безопасности: «закрыть уязвимости в образах». Сделали быстро и правильно, как казалось: сканер в конвейере, блокировка деплоя при находках уровня High и Critical, дашборд с прогрессом.

В первый день сборка упала у тридцати восьми сервисов из сорока одного. Причина — уязвимость в системной библиотеке базового образа, которую нельзя починить со стороны приложения. Через два часа в чат платформы пришёл директор по продукту с вопросом, почему встал релиз. Через четыре часа появилась метка security-exception: true, которая пропускает проверку, — как временное решение на неделю.

Через полгода метку несут 74 % деплоев. Дашборд показывает 91 % покрытия сканированием и ноль незакрытых Critical — потому что всё, что не закрыли, помечено исключением, а исключения в отчёт не попадают. Служба безопасности отчитывается о результате. Платформа получила репутацию тормоза. Реальный уровень защищённости не изменился ни на процент: единственное, что изменилось, — теперь в компании есть общий, всем известный и социально одобренный способ обойти любую проверку.

Это не история про плохой сканер. Это история про то, что безопасность в платформе — это продуктовая работа с теми же законами, что и всё остальное в этом треке. У неё есть пользователи — инженеры продуктовых команд. У пользователей есть альтернатива. Если контроль дороже обхода, будет обход, и вопрос лишь в том, оформят его меткой или сделают молча.

В этой главе — три предметные области, в которых платформа реально может дать больше, чем регламент в вики: секреты и идентичность, доступы, доказательства соответствия. И к каждой — цена: во времени платформенной команды, во времени продуктовых команд и в стоимости владения инструментами.

Почему безопасность в платформе — про принятие, а не про полноту

Служба безопасности и платформа считают разными единицами, и в этом корень большинства конфликтов.

Служба безопасности измеряет покрытие: сколько контролей внедрено, сколько находок закрыто, сколько политик написано. Это её локальный оптимум — и он честно оптимизируется, вплоть до состояния, когда покрытие 100 %, а работать невозможно. Классическая локальная оптимизация, разобранная в systems-thinking: каждый участник улучшает свой показатель, а система в целом деградирует.

Платформа обязана измерять другое — долю потока, который проходит через защищённый путь:

  • сколько продовых нагрузок ходит в базу по короткоживущему токену, а не по паролю из конфига;
  • сколько деплоев прошло без метки исключения;
  • сколько доказательств для аудита собралось автоматически, а не руками накануне.

Разница принципиальная. Контроль, который покрывает 100 % сервисов, но обходится в 74 % случаев, защищает 26 % флота. Контроль, который покрывает 60 % сервисов и не обходится никогда, защищает 60 %. Второй лучше, хотя в отчёте выглядит хуже.

Отсюда рабочее определение, вокруг которого построена вся глава:

Безопасность по умолчанию — это состояние, при котором безопасный вариант оказывается самым дешёвым по времени и когнитивной нагрузке. Не единственным доступным, а самым дешёвым.

«Не единственным» — важная оговорка. Как только безопасный путь становится единственным, он перестаёт быть золотым путём и превращается в забор, а забор порождает подкопы. Про то, как выглядит легальный съезд с пути, разговор будет в разделе про исключения.

Есть и вторая причина, по которой платформа — правильное место для безопасности, и она чисто экономическая. Платформа уже стоит на пути каждого изменения: конвейер, реестр образов, выдача инфраструктуры, приёмка. Добавить контроль в место, через которое поток и так идёт, стоит на порядок дешевле, чем поставить сорок команд перед сорока чек-листами. Это прямое применение точек воздействия: изменение значения по умолчанию — рычаг сильнее, чем добавление правила поверх старого умолчания.

Именно этот график расхождения — единственный честный аргумент за платформенную безопасность. Он же говорит, когда её строить не надо: при пяти командах линия «чек-лист» дешевле, и никакая архитектурная красота этого не перевешивает. К расчёту вернёмся отдельно.

Секреты: проблема не в шифровании, а в числе живых копий

Начнём с первых принципов. Секрет — это данные, обладание которыми даёт доступ. Всё, что о нём важно, следует из одного свойства: секрет копируется без следа. Вы не узнаете, что копия сделана, и не сможете её найти.

Из этого следуют два вывода, которые переворачивают привычную постановку задачи.

Вывод первый: шифрование хранилища решает наименее важную часть проблемы. Секрет в покое почти никогда не утекает — утекает копия в пути: в переменной окружения CI, в логе сборки, в слое образа, в дампе памяти, в тикете, в чате, в .env на ноутбуке уволившегося подрядчика. Хранилище с шифрованием нужно, но это гигиена, а не решение.

Вывод второй: главная метрика секрета — не «где лежит», а «сколько стоит отозвать». Если отзыв стоит недель координации, ротации не будет. Не потому что люди ленивы, а потому что цена реальна и её никто не оплатит.

Радиус поражения секрета и цена отзыва

Лестница зрелости: от пароля в конфиге до отсутствия секрета

Ступень Как выглядит Время жизни Цена отзыва Что происходит при утечке
0. Секрет в репозитории пароль в config.yaml вечность недели утечка навсегда, история git её хранит
1. Секрет в переменных CI вписан руками в настройки годы дни доступен всем, кто может запустить job
2. Хранилище с ручной выдачей Vault, инженер копирует значение месяцы дни копия уже разошлась, отзыв неполный
3. Хранилище с автоподстановкой оператор кладёт в под при старте недели часы окно ограничено сроком жизни секрета
4. Короткоживущий токен по идентичности обмен идентичности на токен на 15 мин минуты минуты утечка есть, доступа нет
5. Секрета не существует mTLS-сертификат, выданный автоматически минуты минуты нечего красть в статике

Ступени 0–2 отличаются от 3–5 качественно, а не количественно. На ступенях 0–2 секрет — это значение, которым владеет человек. На ступенях 3–5 это производная от идентичности, и человек его не видит вовсе.

Практический перевод: цель платформы — не «завести Vault», а убрать долгоживущие ключи с путей, где ходит поток. Порядок работ, который окупается быстрее всего:

  1. Убить долгоживущие облачные ключи в CI. Это одна конфигурация и самая большая разовая победа. GitHub Actions, GitLab CI и большинство систем умеют выдавать OIDC-токен, который облако обменивает на временную роль (документация GitHub про OIDC). После этого в настройках репозиториев не остаётся ни одного ключа доступа к облаку — самой опасной категории.
  2. Дать нагрузкам идентичность. В Kubernetes это service account, привязанный к облачной роли; в общем виде — SPIFFE/SPIRE с проверяемым идентификатором нагрузки (spiffe.io).
  3. Перевести на неё базы и внутренние вызовы. Большинство managed-СУБД умеют аутентификацию по IAM-токену; внутренние вызовы — по mTLS.
  4. Оставшееся — в хранилище с автоподстановкой, без ручного копирования.
# Обмен идентичности рабочей нагрузки на короткоживущий доступ к базе.
# Ключевая деталь: в коде нет ни пароля, ни пути к файлу с паролем —
# есть только имя роли и утверждение о том, кто мы такие.
import time
import boto3

class DbCredentials:
    """Токен живёт 15 минут; обновляем заранее, чтобы не ловить отказ в пике."""

    REFRESH_MARGIN_SEC = 120  # обновляем за 2 минуты до истечения

    def __init__(self, host: str, port: int, user: str, region: str):
        self._host, self._port, self._user = host, port, user
        self._client = boto3.client("rds", region_name=region)
        self._token: str | None = None
        self._expires_at: float = 0.0

    def token(self) -> str:
        now = time.monotonic()
        if self._token is None or now > self._expires_at - self.REFRESH_MARGIN_SEC:
            # Вызов подписывается идентичностью, которую среда выдала процессу
            # (в Kubernetes — проецируемый service account token).
            # Секрета, который можно было бы украсть из образа, здесь нет.
            self._token = self._client.generate_db_auth_token(
                DBHostname=self._host, Port=self._port, DBUsername=self._user
            )
            self._expires_at = now + 15 * 60
        return self._token

Обратите внимание на то, чего в этом коде нет: чтения файла, переменной окружения, обращения к внешнему хранилищу секретов. Ступень 4 убирает не только секрет, но и целый класс кода вокруг него — и вместе с ним класс инцидентов «сервис не поднялся, потому что не смог достучаться до хранилища».

Жизненный цикл секрета и почему «ротация раз в 90 дней» — плохая цель

Календарная ротация — это ритуал, а не контроль. Она не отвечает на вопрос, который задают в момент инцидента: за сколько мы сможем отозвать и заменить конкретный ключ прямо сейчас?

Правильная величина — время до полного отзыва (по сути MTTR для секрета). Её надо измерять учением, а не декларировать: выбрать один продовый секрет, объявить его скомпрометированным и провести полную замену, засекая время. Это тот же жанр, что и учения из SRE, и результат первого прогона обычно отрезвляет: там, где ожидали час, получается три дня, и половина времени уходит на поиск владельца.

Два состояния в этой схеме обычно отсутствуют в реальных системах, и оба дорого стоят.

«Осиротел». Секрет, у которого нет живого владельца, — это ресурс, который никто не решится отозвать. Лечится связкой с каталогом владения из главы про инфраструктуру как API: у секрета обязано быть поле владельца, ссылающееся на живую группу, и автоматическая проверка, что группа существует и в ней есть люди.

«Подозрение утечки». Когда сканер находит ключ в коммите, типовая реакция — переписать историю и закрыть тикет. Это неверно: любой секрет, попавший в репозиторий, считается скомпрометированным независимо от того, удалили вы коммит или нет. Форки, зеркала, кэши CI, локальные клоны — всё это копии. Единственный корректный сценарий — ротация. Платформа обязана сделать этот сценарий дешёвым: кнопка «ротировать» рядом с находкой, иначе процесс не выполнится ни разу.

Технически стоит ставить два барьера, а не один: блокировка push на стороне хостинга (у GitHub это push protection) — она ловит до попадания в историю, и периодический скан всей истории (gitleaks) — он ловит то, что уже там. Первый барьер лучше, потому что даёт обратную связь за секунды и не требует ротации. Детали устройства самих хранилищ разобраны в треке безопасности: управление секретами.

Цена владения хранилищем секретов

Тут пора назвать цифры, потому что «поставьте Vault» звучит как одна задача, а является постоянным обязательством.

Самостоятельно развёрнутый HashiCorp Vault в отказоустойчивой конфигурации — это: кворум узлов и понимание Raft, процедура распечатывания (unseal) и хранение ключей от неё вне самого Vault, резервное копирование с проверкой восстановления, обновления версий без простоя, аудит-лог с ротацией, интеграция с каждым потребителем, отдельная строка в дежурстве. Vault в проде — компонент уровня «упал он — не деплоится и не стартует ничего», то есть его SLO обязано быть строже, чем у сервисов, которые от него зависят (про SLO зависимостей). Реалистичная оценка: 0,3–0,5 постоянного человека на поддержание плюс разовые 1–2 месяца на внедрение.

Managed-альтернатива (secret manager облака) снимает почти всю эту работу и стоит денег за операцию чтения — что тоже надо посчитать, потому что наивная реализация с чтением секрета на каждый запрос выдаёт неожиданный счёт. Промежуточный вариант — External Secrets Operator, который синхронизирует секреты из облачного хранилища в кластер и снимает с приложений знание о хранилище.

Правило выбора простое и скучное: если у вас нет требования, которое managed-хранилище не закрывает, берите managed. Своё разворачивают, когда есть жёсткое требование к размещению данных, работа в нескольких облаках сразу или потребность в динамических секретах для СУБД, которых нет у провайдера. Это ровно тот случай, где применим Choose Boring Technology.

Доступы: три разных вопроса, которые постоянно смешивают

Слово «доступ» покрывает три задачи с несовпадающими требованиями. Смешение — источник самых уродливых платформенных абстракций.

Доступ нагрузки Доступ человека Доступ самой платформы
Кто субъект сервис, job инженер, аналитик контроллеры платформы
Частота миллионы раз в день десятки раз в неделю постоянно
Требование нулевая задержка, без участия человека быстро выдать, обязательно отозвать минимальные права, максимальный аудит
Основной риск избыточные права навсегда забытый доступ у уволенного компрометация = компрометация всего
Механизм идентичность нагрузки, mTLS SSO, короткая сессия, JIT отдельные роли на контроллер, а не одна root-роль

Третья колонка — та, о которой забывают. Платформа по устройству обладает правами создавать инфраструктуру и раздавать доступы, то есть является самой привлекательной целью в компании. Минимум, который здесь обязателен: у каждого контроллера своя роль с правами только на свой класс ресурсов, права платформы на продовые данные отсутствуют (создавать базу — да, читать из неё — нет), и все действия платформы от чужого имени логируются с указанием инициатора. Подробный разбор моделей авторизации — в security.

Наименьшие привилегии как процесс, а не как состояние

Написать минимальную политику доступа заранее невозможно: никто не знает полного списка вызовов, которые сервису понадобятся. Поэтому на практике первая версия политики всегда содержит "*", и там же навсегда остаётся.

Рабочий выход — выводить политику из наблюдений, а не из воображения:

  1. Сервис стартует с широкой политикой, помеченной как временная, со сроком.
  2. Платформа собирает фактически использованные действия (в AWS это Access Advisor и генерация политики по журналам).
  3. Через месяц наблюдений платформа сама открывает пул-реквест с суженной политикой и отчётом «за 30 дней использовано 7 действий из 240 разрешённых».
  4. Команда либо сливает PR, либо добавляет обоснование — и то и другое занимает минуты.

Именно так это работает у Netflix: их инструменты Aardvark и RepoKid автоматически урезают неиспользуемые права в ролях. Ключевое в этом подходе — работу делает платформа, а команде остаётся решение. Обратный порядок (платформа заводит тикет «сузьте свои права») даёт нулевой результат, потому что у команды нет ни данных, ни мотива.

Доступ человека в прод: JIT и аварийный доступ

Постоянный доступ инженера к проду — это долгоживущий секрет в человеческой форме, со всеми теми же свойствами. Замена — выдача по требованию с коротким сроком.

Три детали делают эту схему рабочей, и без любой из них она не взлетит.

Скорость важнее строгости. Если выдача занимает больше 2–3 минут, инженеры добудут постоянный доступ — через тикет, через знакомого, через сервисную учётку с паролем в чате. Автоодобрение для доступа на чтение к своему сервису — не послабление, а условие того, что схемой будут пользоваться.

Аварийный доступ (break-glass) обязателен и обязан быть быстрым. В три часа ночи при лежащем проде дежурный не будет ждать второго одобряющего. Правильная конструкция: аварийная роль выдаётся мгновенно и без одобрения, но её использование поднимает громкий сигнал, пишет полную сессию и автоматически создаёт задачу на разбор. Разбор — не наказание, а вопрос «почему штатного пути не хватило»; каждое использование break-glass — это баг в платформе. Тон разговора здесь ровно такой же, как в постмортемах: ищем причину в системе, а не виноватого.

Отзыв при уходе человека обязан быть в одном месте. Единственный надёжный вариант — все доступы производны от членства в группе в каталоге сотрудников; удаление человека из каталога снимает всё. Если хоть один доступ выдан «напрямую этому человеку», у вас в компании навсегда останется набор неизвестных живых доступов.

Инструментов для записи сессий и брокеринга доступа хватает (Teleport, боры доступа облаков, собственный SSH-CA). Все они стоят денег и требуют обслуживания; на масштабе меньше пары десятков инженеров дешевле обходится связка «SSO + короткие роли облака + журнал», без отдельного продукта.

Соответствие требованиям: доказательства как побочный продукт

Здесь платформенные команды теряют больше всего времени зря — потому что неправильно понимают вопрос.

Аудитор не спрашивает «у вас безопасно?». Он спрашивает: «покажите, что заявленный контроль работал непрерывно в течение периода, и дайте выборку доказательств». Ключевые слова — «непрерывно» и «доказательства». Доказательство — это артефакт с меткой времени, субъектом и содержанием: запись в журнале, подписанный отчёт конвейера, история одобрений пул-реквеста.

Отсюда следует главное утверждение раздела: платформа — самый дешёвый производитель доказательств в компании, потому что она и так стоит на пути потока. Один общий конвейер даёт доказательство «код прошёл ревью и тесты перед выкладкой» сразу для всех сорока команд, автоматически и без единого интервью. Сорок разных конвейеров дают сорок интервью и сорок папок со скриншотами.

Типовой контроль Где реализован в платформе Что становится доказательством
Изменения проходят ревью защита ветки, обязательное одобрение история PR: автор, ревьюер, время
Разделение обязанностей автор PR не может его одобрить тот же журнал; выкладку делает автоматика, а не человек
В прод попадает только собранное в CI приёмка требует подписи образа подпись cosign и отчёт о происхождении
Известен состав ПО генерация SBOM в конвейере SBOM, привязанный к цифровому отпечатку образа
Доступ по принципу минимальных прав роли из каталога владения выгрузка «кто к чему имел доступ» на любую дату
Доступ отзывается при уходе производность от каталога сотрудников журнал синхронизации
Данные шифруются при передаче и хранении mTLS по умолчанию, шифрование томов конфигурация в git плюс проверка на приёмке
Уязвимости устраняются в срок конвейер обновления зависимостей распределение времени от появления CVE до выката
Действия в проде журналируются брокер доступа, аудит облака журнал сессий

Практический вывод, который экономит кварталы: не стройте «портал соответствия», в который люди руками загружают скриншоты. Это самый частый вид платформенного продукта, которым не пользуются: он не даёт пользователю ничего, а требует работы. Если доказательство нельзя собрать автоматически из системы, которая и так работает, — вопрос не в портале, а в том, что контроль на самом деле не реализован.

Про сами стандарты стоит знать ровно одно: они говорят о процессе и доказательствах, а не о технологиях. Ни SOC 2, ни ISO/IEC 27001 не требуют конкретного инструмента; PCI DSS более предметен, а GDPR и 152-ФЗ добавляют требования к обработке персональных данных и местам их хранения — там начинаются архитектурные ограничения, которые платформа обязана уметь выражать (например, «эти данные не выходят из региона» как политика, проверяемая на приёмке). Содержательный разбор — в security. Полезные инженерные ориентиры, на которые можно опереться, не изобретая свой список: NIST SSDF (SP 800-218), SLSA, OWASP ASVS, CIS Benchmarks.

И честная оговорка про мотив. Часто настоящая причина заниматься соответствием — не риск, а продажи: без отчёта SOC 2 не подписывается контракт с крупным клиентом. Это нормальный, измеримый бизнес-аргумент, и его надо называть вслух. Он же задаёт правильный объём работ: закрыть требования аудита, а не построить идеальную безопасность.

Точки контроля: где ставить проверку и во что она обходится

У любого контроля есть место установки, и от места зависят три вещи: задержка обратной связи, цена исправления и вероятность того, что контроль обойдут.

Четыре точки контроля: задержка обратной связи и цена исправления

Правило одно: контроль ставится в самой левой точке, где его можно проверить детерминированно. Правее — только то, что левее в принципе не проверяется. Проверка «образ подписан» невозможна в редакторе, потому что образа ещё нет, — ей место на приёмке. Проверка «в манифесте нет привилегированного контейнера» прекрасно делается в редакторе схемой и в PR политикой; выносить её только на приёмку — значит специально ронять деплой в момент, когда команда уже под давлением срока.

Когда контроль имеет право блокировать

Блокирующая проверка — это обещание пользователю. Нарушенное обещание стоит доверия, которое возвращается кварталами. Критериев права на блокировку три, и нужны все:

  1. Детерминированность. Одинаковый вход даёт одинаковый результат. Проверка, зависящая от внешней базы уязвимостей, которая обновилась ночью, недетерминирована: вчера собиралось, сегодня нет, код не менялся.
  2. Действие в сообщении. Отказ обязан содержать: что нарушено, где именно (файл, строка), как починить, и ссылку на исключение, если починить нельзя. «Policy violation: PSP-0042» — это не сообщение, это оскорбление.
  3. Низкий уровень ложных срабатываний. Порог здесь жёстче, чем кажется: при 5 % ложных срабатываний и десяти проверках на деплой каждый второй деплой ловит ложный отказ, и через месяц проверкам перестают верить в принципе.

Не проходящее по критериям остаётся предупреждением и метрикой. Это не поражение: метрика с именем владельца работает лучше блокировки без него, потому что попадает в бэклог, а не в обход.

Отдельно про верхний правый угол — «CVE Critical в базовом образе». Это ровно тот случай из начала главы. Цена пропуска высокая, но ложных и неустранимых срабатываний столько, что блокировка не работает. Рабочее решение не «блокировать» и не «забить», а изменить умолчание: платформа сама поставляет и обновляет базовые образы, сама открывает пул-реквесты с обновлением, и тогда проверка ловит уже единицы случаев, а не тридцать восемь сервисов сразу.

Как вводить новую политику, не устроив забастовку

Мгновенное включение блокировки — самый надёжный способ получить метку security-exception на 74 % деплоев. Работает поэтапная раскатка с публичным графиком, ровно как в главе про миграции.

Что здесь принципиально:

  • Отчёт до включения. Вы обязаны знать список затронутых сервисов и команд до того, как что-то сломается. Если такого отчёта нет — вы не готовы к раскатке.
  • Платформа чинит большинство случаев сама. Автоматический PR с исправлением превращает «сделайте работу» в «нажмите слить». Это то самое различие между продуктом и налогом, которое проходит через весь трек.
  • Блокировка сначала для новых. Новый сервис ничего не ломает, а поток новых сервисов постепенно сдвигает распределение.
  • Исключения со сроком и владельцем. Не «метка в конфиге», а запись в реестре: сервис, причина, кто разрешил, до какой даты, ссылка на задачу по устранению. Автопродление запрещено; истечение срока создаёт задачу. Пустой реестр исключений — не признак порядка, а признак того, что исключения оформляют мимо вас.

Типовые провалы

Обёртка над IAM облака, которая только мешает

Платформа заводит свой формат описания прав и транслирует его в политики облака. Мотив понятен: «спрятать сложность IAM». Результат: чтобы отладить отказ в доступе, инженер обязан понимать и IAM, и вашу схему, и правила трансляции между ними. Сообщение об ошибке приходит от облака в терминах облака, а написано было в терминах платформы — сопоставить их некому.

Признак того, что вы в этой ловушке: на каждое обращение в поддержку платформы вы отвечаете переводом с языка облака на свой язык. Это чистая косвенность, за которую платят чужим временем; подробный критерий — в главе про абстракции.

Обёртка оправдана в двух случаях. Первый: вы даёте не другой синтаксис, а другой уровень — «сервис A читает из очереди B», из чего выводятся все нужные политики. Второй: вам реально нужна переносимость между облаками, и это подтверждено решением, а не мечтой. Во всех остальных случаях лучше дать готовые именованные наборы прав на родном языке облака и хороший инструмент диагностики отказов.

Портал соответствия, которым никто не пользуется

Двести контролей в вики, красивый дашборд, ручная загрузка подтверждений раз в квартал. Пользуются им два человека из службы безопасности перед аудитом. Инженеры не открывали его ни разу.

Диагноз простой: инструмент не даёт пользователю ничего, что нужно ему самому. Работающая альтернатива — показывать состояние соответствия там, где инженер и так находится: в пул-реквесте, в описании сервиса, в CLI. И собирать доказательства из систем, а не из людей. Это в чистом виде платформа как продукт: если никто не пользуется, продукта нет, независимо от вложенных усилий.

Одна абстракция поверх трёх разных потребностей

Самый дорогой провал в этой главе, потому что он выглядит как хорошая инженерия. Платформа делает единый интерфейс secrets.get("имя") и накрывает им три вещи:

Пароль к внешнему API Сертификат mTLS Ключ подписи артефактов
Время жизни месяцы, ротация по договорённости с партнёром часы, ротация автоматическая годы, ротация — событие
Кто выдаёт человек, вручную, вне вашего контура внутренний удостоверяющий центр церемония с несколькими участниками
Как используется при каждом вызове при установке соединения редко, при выпуске релиза
Требование к аудиту факт чтения не нужен, объём слишком велик каждое использование, поимённо
Где обязан жить хранилище память процесса, на диск не пишется HSM или keyless-схема

Общего у них — только слово «секрет». Единый интерфейс либо опускается до наименьшего общего знаменателя (и тогда для сертификатов не хватает автоматической ротации, а для ключа подписи — аудита каждого использования), либо обрастает флагами до состояния, в котором его невозможно ни объяснить, ни поменять. Правильный ответ — три разных механизма с честными именами: хранилище секретов, cert-manager или его аналог, keyless-подпись через Sigstore. Три простых механизма дешевле одного универсального.

Безопасность как налог: политику пишет один, платят другие

Служба безопасности выпускает требование. Платформа реализует. Продуктовые команды тратят на приведение в соответствие по несколько дней каждая. Ни у кого нет строки «сколько это стоило», потому что затраты распределены по сорока бэклогам и не видны ни в одном отчёте.

Лекарство административное, а не техническое: у каждого требования обязана быть оценка совокупной стоимости внедрения до принятия решения. Формулировка для разговора: «это требование стоит примерно 34 команды × 6 часов = 204 часа плюс 3 недели платформенной работы; какой риск оно снимает и есть ли вариант дешевле?». Часто выясняется, что вариант дешевле есть — обычно это изменение умолчания вместо добавления проверки. Про то, как ведут такие разговоры и почему граница ответственности команд здесь ключевая, — в engineering-leadership.

Культ инструментов

Ни один инструмент из этой области не бесплатен, и цену стоит называть вслух.

  • Движки политик (OPA Gatekeeper, Kyverno). Дают декларативные правила на приёмке. Цена: у OPA — собственный язык Rego с непривычной моделью вычисления и нетривиальной отладкой; у обоих — вебхук в критическом пути кластера. Вебхук с failurePolicy: Fail при недоступности останавливает создание подов во всём кластере — это реальный способ устроить полный отказ платформы политикой. Обязательны: исключение системных пространств имён, запас реплик, режим Ignore на время раскатки, тесты политик в CI (документация Kubernetes про admission-вебхуки). Прежде чем ставить движок, проверьте, хватает ли встроенных Pod Security Standards — часто хватает.
  • Vault. Разобран выше: 0,3–0,5 человека постоянно, критичность выше, чем у сервисов-потребителей.
  • Service mesh ради mTLS. Даёт шифрование и идентичность между сервисами без изменения кода. Цена: sidecar у каждого пода (память и задержка), собственный слой отказов, отдельная экспертиза, болезненные обновления. Если mTLS нужен только на периметре или между тремя сервисами, mesh — избыточен.
  • Сканеры. Полезны; вредны, когда включены на блокировку без работы с базовыми образами и без автопатчей.
  • Backstage и порталы. Витрина не создаёт безопасности. Если контроль не реализован в конвейере и на приёмке, красивая карточка в каталоге показывает статус несуществующего контроля.

Общий принцип, который стоит держать при выборе: инструмент решает задачу «как выразить правило», а не задачу «как сделать так, чтобы правило соблюдали». Вторая задача — продуктовая, и никакой инструмент её за вас не решит.

Сколько это стоит и когда окупается

Платформенная команда не пишет продукт. Значит, её работа обязана возвращаться сэкономленным временем других — или снятым риском, выраженным в деньгах. Посчитаем честно, включая неприятную часть.

Возьмём компанию: 40 продуктовых команд, около 200 инженеров. Экономия на одной команде в год при работающем платформенном контуре безопасности:

Статья Без платформы, ч/год на команду С платформой Экономия
Возня с секретами и доступами 18 4 14
Подготовка к аудиту (интервью, выгрузки, скриншоты) 8 1 7
Кампании массового обновления (2 в год) 12 3 9
Ожидание доступа при инцидентах 6 1 5
Итого 44 9 35

40 команд × 35 ч = 1400 часов в год.

Теперь цена. Платформенный контур безопасности — это примерно 1,2 постоянного человека (выдача идентичности, хранилище, политики, автопатчи, поддержка) ≈ 1900 рабочих часов, плюс лицензии и инфраструктура в эквиваленте ещё 0,3 человека ≈ 480 часов. Итого около 2400 часов.

1400 меньше 2400. Экономия на рутине покрывает примерно 58 % затрат, и на этом месте надо остановиться и сказать вслух неприятное: если считать только сэкономленную рутину, платформенная безопасность обычно не окупается. Это отличает её от конвейера или окружений, где счёт сходится на прямой экономии.

Остаток закрывают три слагаемых, и их надо считать явно, а не подразумевать.

Ожидаемый ущерб. Вероятность серьёзного инцидента с утечкой долгоживущего ключа — величина, которую можно оценить по собственной истории и по отраслевым данным. Пусть 15 % в год. Стоимость такого инцидента для компании этого размера — расследование, тотальная ротация, простой, юридическая работа, отчёт клиентам — эквивалент 2500–4000 часов. Ожидаемая величина: 0,15 × 3000 ≈ 450 часов в год, и она снижается кратно при переходе на короткоживущие доступы.

Скорость массового обновления. Это, пожалуй, главный продукт платформенной безопасности. Когда выходит уязвимость уровня Log4Shell (предупреждение CISA по CVE-2021-44228), вопрос стоит так: за сколько вы обновите 95 % флота? Компания с общими базовыми образами и автопатчами делает это за дни; компания с сорока своими сборками — за недели, при этом инженеры работают ночами, а окно эксплуатации открыто всё это время. Разница и в прямых часах, и в вероятности ущерба.

Возможность продавать. Отчёт SOC 2 или аналог как условие сделки — это не «безопасность», это выручка. Если такой контракт есть, он один закрывает весь расчёт, и тогда объём работ надо определять от требований аудита, а не от идеала.

С учётом всех слагаемых картина обычно сходится в диапазоне 25–40 команд. Ниже — не сходится, и это не повод «внедрять на вырост».

Когда не строить. 5 команд, 25 инженеров, один аудит в год. Тут выигрывает скучный набор: SSO с обязательным вторым фактором, managed secret manager облака, OIDC-федерация вместо ключей в CI, включённая защита от push с секретом, одна страница правил и раз в квартал общая ревизия доступов на час. Совокупно — примерно 0,2 человека, покрывает подавляющее большинство реального риска и не создаёт ни одного нового компонента, который может упасть. Это полностью соответствует логике последней главы трека.

Что измерять

Метрики этой главы делятся на две группы, и путать их нельзя.

Метрики принятия — отвечают на вопрос «пользуются ли безопасным путём»:

Метрика Как считать Целевое поведение
Доля нагрузок без долгоживущих ключей по инвентарю секретов и ролей главная метрика; растёт медленно, падает при каждом новом легаси
Доля деплоев с меткой исключения из журнала конвейера больше 5 % — контроль не работает, а имитируется
Число активных исключений и медианный возраст из реестра возраст важнее числа: старые исключения — это отказ от контроля
Доля доступов в прод, выданных по требованию против постоянных постоянные доступы обязаны стремиться к нулю
Использование break-glass случаев в месяц не ноль (иначе им побоятся пользоваться) и не десятки
Доля доказательств, собранных автоматически из подготовки к аудиту ниже 70 % — вы будете тратить недели перед каждым аудитом

Метрики результата — отвечают на вопрос «стало ли безопаснее»:

Метрика Как считать Почему важна
Время до полного отзыва секрета учением, не оценкой реальная готовность к инциденту
Время от выхода CVE до 95 % обновлённого флота по инвентарю версий главный продукт платформенной безопасности
Доля секретов старше 12 месяцев по метаданным хранилища прокси для «ротация не работает»
Число доступов у уволившихся спустя сутки сверкой с каталогом сотрудников любое ненулевое значение — дефект процесса
Медианное число разрешённых действий на роль против использованных из журналов показывает, движетесь ли вы к минимальным правам
Доля сервисов с известным владельцем из каталога без владельца не работает ни один контроль

Отдельно стоит смотреть на поток обращений в поддержку с формулировкой «не понял, почему не пустило». Это лучший ранний индикатор того, что контроль скоро начнут обходить: непонятный отказ рождает не исправление, а поиск обхода. Про то, как собирать такие сигналы честно, — в главе про опыт разработчика.

План на квартал, если начинать с нуля

Порядок здесь не произвольный: каждый следующий шаг опирается на предыдущий, и первые три дают львиную долю эффекта.

  1. Инвентарь и владение (2 недели). Список продовых нагрузок, у каждой — живая группа-владелец. Без этого не работает ничего дальше. Побочный результат: вы найдёте сервисы, о которых никто не помнил.
  2. Убить облачные ключи в CI (2 недели). OIDC-федерация вместо статических ключей доступа. Самая большая разовая победа за самые скромные деньги.
  3. Защита от push с секретом плюс скан истории (1 неделя). Плюс написанный и опробованный сценарий ротации при находке.
  4. Идентичность нагрузок и первый сервис на короткоживущем доступе к базе (3–4 недели). Один сервис целиком, до конца, с честным замером трудозатрат — это ваш образец и ваша оценка для остальных.
  5. Базовые правила приёмки в режиме предупреждения (2 недели). Пять-шесть правил, не пятьдесят. Отчёт «кого затронет» публикуется сразу.
  6. Автосбор доказательств (2 недели). Выгрузка по трём-четырём контролям, которые аудитор спросит наверняка.
  7. Только потом — движок политик, свой портал, mesh и всё остальное, что стоит постоянных людей.

Пункты 1–3 занимают около пяти недель и снимают, по опыту, большую часть реального риска. Пункты 4–6 — это уже платформа. Пункт 7 требует ответа на вопрос про окупаемость из предыдущего раздела.

Мини-итог

  • У безопасности в платформе те же законы, что у остальной платформы: есть пользователи, есть альтернатива, и контроль дороже обхода будет обойдён. Метрика — доля потока через защищённый путь, а не число внедрённых контролей.
  • Проблема секрета — не шифрование, а количество живых копий и цена отзыва. Лестница ведёт от «значения, которым владеет человек» к «производной от идентичности»; ступени 4–5 меняют природу риска, а не его величину.
  • Календарная ротация — ритуал. Осмысленная величина — время до полного отзыва, и её надо измерять учением. Секрет, попавший в репозиторий, скомпрометирован независимо от переписывания истории.
  • «Доступ» — это три разные задачи: нагрузки, человека и самой платформы. У платформы самые опасные права в компании, и её собственная модель доступа обязана быть строже всех прочих.
  • Минимальные привилегии достигаются наблюдением и автоматическим PR от платформы, а не тикетом «сузьте свои права».
  • Аварийный доступ обязателен, обязан быть мгновенным и обязан вызывать разбор, а не наказание. Каждое его использование — баг в платформе.
  • Соответствие требованиям — это доказательства с меткой времени. Платформа дёшево производит их как побочный продукт; портал с ручной загрузкой скриншотов не производит ничего.
  • Контроль ставится в самой левой точке, где проверяется детерминированно. Право блокировать даётся только при детерминированности, действии в сообщении и низком уровне ложных срабатываний; остальное — метрика с владельцем.
  • Новая политика раскатывается этапами: наблюдение, отчёт «кого затронет», автопатч от платформы, блокировка для новых, потом для всех. Исключения — со сроком, владельцем и задачей.
  • На одной сэкономленной рутине безопасность в платформе обычно не окупается. Считать надо вместе с ожидаемым ущербом, скоростью массового обновления флота и возможностью продавать. Точка окупаемости — около 25–40 команд; ниже дешевле скучный набор из SSO, managed-хранилища и федерации без единого нового компонента.

Источники

Что дальше

Безопасность оказалась не техническим слоем, а продуктовым: она работает ровно настолько, насколько безопасный путь дешевле обхода, и её ценность приходится доказывать числами, а не пугалками. Ровно та же логика ждёт нас в разговоре о деньгах — с одним отличием: там счёт видит бухгалтерия, а значит, разговор начнётся сам, независимо от того, готовы вы к нему или нет. Платформа тратит чужой бюджет, показывает его командам и обязана уметь объяснить, за что именно.

Стоимость: учёт расходов, лимиты и разговор с командами о деньгах

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов