Подборки вопросов: DevOps · SRE · DevSecOps · MLOps · AIOps
Блок 1. Основы DevSecOps
1. Что такое shift-left и как внедрять его в пайплайн?
Shift-left — перенос проверок безопасности влево по конвейеру: из прода и предрелизного аудита в момент написания кода. Аргумент — экономика: баг, пойманный линтером в IDE, стоит минуты; тот же баг, найденный пентестом в проде, — это фикс, релиз, ретест, а если его нашли не пентестеры — ещё и инцидент с разбором. Разница в стоимости — порядки, и именно с этой цифры стоит начинать ответ. Внедрение слоями: pre-commit-хуки (поиск секретов, линтеры) → проверки на PR (SAST, сканирование зависимостей — быстрые, минуты) → сборка (скан образа, IaC) → деплой (admission-политики) → прод (runtime-мониторинг). Ключевой принцип: чем левее проверка, тем быстрее она обязана работать и тем точнее — иначе разработчики научатся её обходить. Shift-left не отменяет правую часть: DAST, пентесты и runtime-детект остаются, просто до них доезжает меньше мусора.
Кандидаты рассказывают лозунг «безопасность с первого коммита» и не могут назвать конкретные ступени: что именно гоняется на pre-commit, что на PR, что на сборке. Без этой раскладки ответ — маркетинг, а не инженерия.
Follow-up интервьюера: что нельзя сдвинуть влево в принципе? — то, что видно только на работающей системе: DAST, runtime-поведение, дрифт конфигурации в проде. Shift-left — это «раньше», а не «вместо».
2. Чем DevSecOps отличается от «отдела ИБ со сканером»?
Классическая модель: безопасность — отдельный отдел, который проверяет релиз на выходе и возвращает список замечаний. Узкое место очевидно: релизов десятки в день, безопасников трое, проверка превращается в очередь, а замечания приходят через неделю после того, как разработчик забыл контекст. DevSecOps встраивает безопасность в процесс, а не в отдел: проверки живут в пайплайне и срабатывают автоматически, политики описаны кодом и ревьюятся как код, ответственность за безопасность своего сервиса несёт команда, которая его пишет, — как DevOps сделал с эксплуатацией. Роль security-инженеров при этом меняется, а не исчезает: они строят платформу и гардрейлы (безопасные шаблоны, политики, инструменты), разбирают сложные случаи и учат команды — вместо того чтобы вручную смотреть каждый релиз. Формула для собеса: ИБ-отдел масштабируется людьми, DevSecOps — автоматикой; первый говорит «нельзя», второй строит дорогу, по которой безопасно можно.
Отвечают «это когда все отвечают за безопасность» — и всё. Фраза без механики (проверки в пайплайне, политики как код, гардрейлы вместо ручного аудита) звучит как пересказ вакансии, и интервьюер это слышит сразу.
Follow-up интервьюера: если за безопасность отвечают все — не значит ли это, что никто? — значит, если нет владельца процесса: команда отвечает за свой сервис, security-команда — за платформу, политики и разбор инцидентов. Ответственность распределена, но адресна.
3. Security gates в CI/CD — где ставить и как не заблокировать разработку?
Гейт — точка пайплайна, где проверка безопасности может остановить продвижение артефакта. Классические места: PR (SAST, секреты, зависимости), сборка (скан образа), деплой (admission-контроль, верификация подписи). Главная развилка — blocking против advisory. Блокирующий гейт роняет пайплайн; совет — пишет отчёт и пропускает. Включать всё в blocking с первого дня — верный способ похоронить внедрение: сканер найдёт сотни исторических находок, пайплайны встанут, и через неделю гейт отключат навсегда. Рабочая стратегия: начинать в advisory, собрать статистику, вычистить false positives, зафиксировать baseline (старые находки не блокируют, новые — блокируют), потом переводить в blocking постепенно — сначала critical, потом high. Плюс явный процесс исключений: waiver с владельцем, причиной и сроком действия, а не вечный «игнор-лист». Как устроен сам конвейер и где в нём стадии — база в DevOps-подборке; здесь проверяют умение вписать безопасность, не убив скорость поставки.
Отвечают «блокировать всё критичное» без слова про baseline и разгребание истории. Вопрос «включил Trivy, он нашёл 400 CVE в первый день — твои действия?» валит именно их.
Follow-up интервьюера: разработчик просит исключение «на один релиз» — как оформить? — waiver как код: конкретная находка, владелец, обоснование, дата истечения. Просроченный waiver снова блокирует — иначе исключения бессмертны.
4. Как продать безопасность команде, которая «и так релизит»?
Не страшилками и не приказом — экономикой и удобством. Первое: говорить на языке команды. Не «у вас 300 уязвимостей», а «вот три, которые эксплуатируются из интернета, фикс каждой — обновить версию в одном файле». Второе: снизить цену участия до нуля — безопасный вариант должен быть вариантом по умолчанию: шаблон сервиса уже с securityContext, базовый образ уже минимальный, секреты уже ходят через Vault. Команда получает безопасность, не делая ничего. Третье: не приносить проблемы без решений — каждая находка сканера приходит с конкретным фиксом или авто-PR, а не с требованием «разберитесь». Четвёртое: показать инцидент на цифрах — сколько стоил простой, разбор и ротация после ближайшей утечки в индустрии или своей компании. И честность про приоритеты: если требовать чинить всё подряд, не почините ничего; договоритесь про SLA на critical и high, остальное — фоном. Безопасность продаётся так же, как любое изменение процесса: пилот на одной команде, измеримый результат, потом масштабирование.
Отвечают «нужно обучать и доносить важность». Интервьюер ждёт механику снижения трения: дефолтно-безопасные шаблоны, авто-фиксы, приоритизация — а не веру в силу презентаций.
Follow-up интервьюера: команда отвечает «нам за фичи платят, а не за CVE» — что делать? — эскалировать не на команду, а на модель: риск принимает не инженер, а владелец сервиса, письменно. Обычно желание принять риск письменно испаряется.
5. Объясни модель угроз простыми словами. Что такое STRIDE?
Threat modeling — структурированный ответ на четыре вопроса: что мы строим, что может пойти не так, что мы с этим делаем и хорошо ли мы это сделали. На практике: рисуешь схему системы с потоками данных и границами доверия (интернет/DMZ/внутренняя сеть, юзер/сервис/админ), и для каждого элемента перебираешь классы угроз. STRIDE — мнемоника этих классов: Spoofing (подмена личности), Tampering (подмена данных), Repudiation (отказ от авторства действий), Information disclosure (утечка), Denial of service (отказ), Elevation of privilege (повышение привилегий). Ценность не в аббревиатуре, а в систематичности: без чеклиста находишь угрозы, которые пришли в голову, с чеклистом — проходишь все классы по каждой границе доверия. Ответ «кто атакует и что защищаем» — тоже часть модели: скучающий сканер интернета, конкурент, инсайдер и госструктура — разные бюджеты атаки, и защищаться от всех одинаково — сжечь бюджет. Хорошая модель угроз — короткий живой документ при сервисе, обновляемый при изменении архитектуры, а не толстый PDF на полке.
Расшифровывают STRIDE по буквам и не могут применить: «смоделируй угрозы для CI-пайплайна» вызывает ступор. А это тот же перебор: кто может подменить джобу, украсть секрет, подсунуть артефакт.
Follow-up интервьюера: с чего начнёшь threat modeling в команде, где его не было никогда? — с одной сессии на час по самому критичному сервису: схема на доске, границы доверия, STRIDE по границам. Результат — топ-5 рисков с владельцами, не документ на 40 страниц.
6. OWASP Top 10 — какие пункты реально всплывают в работе DevOps?
Знать все десять полезно, но на собесе DevSecOps копают четыре, которые живут в зоне ответственности инфраструктуры. Security misconfiguration — самый близкий: дефолтные пароли, открытые дашборды (Kibana, Prometheus без аутентификации), включённые debug-эндпоинты, звёздочки в CORS, публичные бакеты. Vulnerable and outdated components — уязвимые зависимости и базовые образы: это про SCA-сканеры и процесс обновления, а не про код. Injection — SQL/командные инъекции: пишут разработчики, но ловит SAST/DAST в пайплайне, который строишь ты, а последствия разгребает инфраструктура. SSRF — сервер делают ходить по чужим URL: для облака это критично, потому что классическая цель — metadata-эндпоинт 169.254.169.254, где лежат креды инстанса; митигация инфраструктурная — IMDSv2, egress-политики, сегментация. Плюс упомяни Broken access control как пункт номер один списка и identification/authentication failures — они всплывают в каждом втором аудите. Сильный ход — сказать, что Top 10 это awareness-документ, а не чеклист безопасности: прошёлся по десяти пунктам — не значит защитился.
Пытаются перечислить все десять по памяти, путаются в порядке и тратят время. Интервьюеру не нужен список — нужно, чтобы кандидат связал пункты со своей работой: misconfiguration, компоненты, SSRF и metadata-сервис.
Follow-up интервьюера: почему SSRF так любят в облаках? — из-за metadata-сервиса: один подделанный запрос изнутри — и у атакующего временные креды роли инстанса. Поэтому IMDSv2 с обязательным токеном — не опция, а норма.
7. Уязвимость, угроза, риск — в чём разница?
Три слова, которые в резюме пишут через запятую, а на собесе просят развести. Уязвимость — слабость системы: непропатченная библиотека, открытый порт, пароль «admin». Угроза — то, что может слабостью воспользоваться: атакующий, малварь, инсайдер, иногда и не злонамеренное — ошибка оператора, пожар. Риск — произведение: вероятность того, что угроза реализуется через уязвимость, умноженная на ущерб. Практическое следствие, ради которого вопрос задают: уязвимость без угрозы и ущерба — не риск. Critical CVE в библиотеке, которая лежит в образе, но не вызывается, в сервисе без доступа из интернета — низкий риск; средняя уязвимость в публичном API платёжного сервиса — высокий. Поэтому управление безопасностью — это управление рисками, а не закрытие всех уязвимостей подряд: ресурсы конечны, и тратить их надо там, где произведение вероятности на ущерб максимально. Отсюда же родом словарь: mitigation снижает вероятность или ущерб, acceptance — осознанное принятие риска владельцем, transfer — страховка и SLA подрядчика.
Используют все три слова как синонимы. Вопрос «critical CVE во внутреннем сервисе без внешнего доступа — это высокий риск?» показывает, различает ли кандидат уязвимость и риск. Правильный ответ начинается со слова «зависит».
Follow-up интервьюера: кто в компании имеет право принять риск? — владелец актива или бизнес-руководитель, письменно и со сроком пересмотра. Инженер риск не принимает — он его оценивает и документирует.
Блок 2. Код и зависимости
8. SAST vs DAST vs SCA vs IAST — что и когда ловит?
SAST — статический анализ исходников без запуска приложения: инъекции, хардкод-секреты, небезопасные функции, path traversal. Работает рано (на PR), видит точную строку кода, но не знает рантайма — отсюда false positives на путях, которые никогда не исполняются. DAST — атака на работающее приложение снаружи, как чёрный ящик: реальные инъекции, misconfiguration заголовков, проблемы аутентификации. Ловит то, что реально эксплуатируется, но поздно (нужен развёрнутый стенд), медленно и не скажет, в какой строке баг. SCA — анализ зависимостей: сверяет список библиотек с базами CVE и лицензии заодно. Ловит чужие баги, которых в твоём коде нет, — а это, по опыту индустрии, большинство находок: современное приложение на 80-90% состоит из чужого кода. IAST — агент внутри работающего приложения: видит и код, и рантайм, точнее обоих, но требует инструментации и приличной нагрузки тестами. Правильная рамка ответа: это не конкуренты, а слои с разной точкой обзора — SAST и SCA на PR, DAST на стенде, и ни один не заменяет остальные.
Путают, что где работает: «DAST сканирует код» — стоп-фраза. И не могут ответить, почему SCA — отдельный класс: свой код может быть идеален, а приложение — дырявым из-за зависимостей.
Follow-up интервьюера: хардкод-пароль в коде — кто из четырёх найдёт? — SAST (и секрет-сканер); DAST не увидит исходников, SCA смотрит только зависимости. Вопрос-проверка, что классы не заучены, а поняты.
9. Какие инструменты поставишь в пайплайн и куда именно?
По стадиям. Pre-commit и PR: gitleaks на секреты, Semgrep как SAST — быстрый, правила пишутся как псевдокод, легко добавлять свои под кодовую базу; SonarQube — если нужен комбайн с качеством кода и техдолгом, но он тяжелее. Тут же SCA: Trivy, Grype или Snyk по lock-файлам — минуты, блокировка по severity. Сборка: Trivy по собранному образу (уязвимости ОС-пакетов плюс зависимости) и по IaC-файлам — один инструмент закрывает три режима: image, fs, config. Стенд: OWASP ZAP в baseline-режиме — пассивный прогон по развёрнутому приложению на каждый релиз, полноценный активный скан — по расписанию, он долгий. Деплой: admission-политики и верификация подписей — это уже кластер. Критерии выбора, которые стоит проговорить: скорость на PR (дольше пяти минут — будут обходить), качество отчётов (разработчик должен понять фикс без security-инженера), API для автоматизации baseline. И честное правило: лучше три инструмента, чьи отчёты реально разбирают, чем восемь, чьи отчёты складываются в артефакты пайплайна навечно.
Перечисляют названия без привязки к стадиям и времени выполнения. «Поставим ZAP на каждый PR» выдаёт, что кандидат ZAP не запускал: активный скан идёт часы, на PR ему не место.
Follow-up интервьюера: Semgrep или SonarQube — по какому критерию выбирать? — Semgrep: скорость, кастомные правила, CI-нативность; SonarQube: платформа с историей, quality gates и покрытием — когда нужен процесс, а не только сканер.
10. Как работать с false positives и не утонуть?
False positives — главный убийца security-автоматизации: если из ста находок девяносто — шум, разработчики перестают читать все сто, и настоящая уязвимость тонет в болоте. Работа с этим — процесс, а не разовая чистка. Первое: триаж каждой находки в первый месяц — подтверждена, ложная, неприменима — и подавление ложных как код: инлайн-аннотации или конфиг подавлений в репозитории с обязательным комментарием почему, ревьюится как код. Второе: baseline — исторические находки отделяются от новых; блокирует пайплайн только новое, старое разгребается фоном по плану. Третье: тюнинг правил — выключить или переписать правила, которые стабильно шумят на твоём стеке; в Semgrep для этого свои правила и --severity, в сканерах зависимостей — фильтр «фикс доступен». Четвёртое: метрика — доля подтверждённых находок по инструменту; если сканер месяцами держит точность ниже 50%, чинить или менять сканер, а не заставлять людей терпеть. И правило гигиены: подавление всегда адресное (конкретное правило в конкретном месте), никогда — глобальное отключение категории.
Отвечают «разбирать руками» без слов baseline, подавление как код и метрика точности. Вторая крайность — «настроим порог severity и забудем»: severity не отличает ложное срабатывание от настоящего critical.
Follow-up интервьюера: разработчик подавил настоящую уязвимость, назвав её ложной — как ловить? — ревью подавлений security-инженером (это маленький диф), выборочный аудит suppression-файлов и срок жизни у подавлений с автопересмотром.
11. SBOM — что это, зачем и какие форматы?
SBOM — software bill of materials, машиночитаемый состав софта: все компоненты, версии, хеши, лицензии, связи между ними. Зачем — три сценария. Первый и главный: реакция на новую CVE. Когда выходит очередной log4shell, вопрос «где у нас эта библиотека?» с SBOM решается запросом к базе за минуты, без — неделей ручного грепа по сотне репозиториев. Второй: требования заказчиков и регуляторов — после атаки на SolarWinds SBOM стал обязательным в госконтрактах США, и волна дошла до энтерпрайза вообще. Третий: лицензионный комплаенс. Форматы два: SPDX (стандарт Linux Foundation, ISO) и CycloneDX (OWASP, более развит вокруг security-сценариев) — уметь генерировать оба, конвертеры есть. Генерация: Syft или Trivy по образу или файловой системе на этапе сборки, артефакт прикладывается к релизу. Важная часть зрелого ответа: SBOM должен генерироваться пайплайном на каждую сборку и подписываться вместе с артефактом (cosign attest) — SBOM, сделанный руками раз в квартал, устаревает к обеду; и он нужен не сам по себе, а вместе с базой, по которой можно спросить «какие сервисы содержат пакет X версии Y».
Определение дают, а на «зачем» отвечают «для порядка». Ключевой сценарий — минуты вместо недели при новой критичной CVE — не называет большинство, хотя именно он оправдывает всю затею.
Follow-up интервьюера: SBOM есть — почему сканер зависимостей всё ещё нужен? — SBOM — это состав, сканер — сверка состава с базами уязвимостей. SBOM без непрерывной сверки — просто опись имущества.
12. Dependency confusion и typosquatting — как защищаться?
Две атаки на пакетные менеджеры. Typosquatting — пакет с именем-опечаткой (requets вместо requests): разработчик ошибся при установке — и выполнил чужой код; вредонос обычно сидит в install-скриптах, то есть срабатывает прямо на npm install, до всякого запуска приложения. Dependency confusion хитрее: атакующий публикует в публичный registry пакет с именем твоего внутреннего пакета, но большей версией — и резолвер, который смотрит в оба источника, приносит публичный «апгрейд»; так Алекс Бирсан в 2021-м зашёл в десятки корпораций, включая Apple и Microsoft. Защита: приватный registry как единственный источник (Nexus/Artifactory в режиме прокси, прямой доступ к публичным репозиториям с билд-агентов закрыт); для внутренних пакетов — зарезервированные неймспейсы (scoped packages @company/ в npm, зарегистрированные и в публичном registry, чтобы их нельзя было занять); lock-файлы с хешами в каждом репозитории — установка ровно того, что зафиксировано, любое расхождение — ошибка сборки; и запрет install-скриптов, где стек позволяет (--ignore-scripts). Плюс карантин новых пакетов: зависимость, впервые появившаяся в организации, проходит проверку до попадания в прокси.
Знают слово, но не механику резолвера: почему публичный пакет с версией 99.0.0 побеждает внутренний 1.2.0. Без понимания «резолвер берёт большую версию из любого источника» защита выбирается наугад.
Follow-up интервьюера: lock-файл с хешами есть — от чего он не спасает? — от компрометации самого пакета до фиксации: если вредоносная версия попала в lock при обновлении, хеши честно её закрепят. Поэтому нужен ещё и карантин/ревью обновлений.
13. Вышла критичная CVE в базовой библиотеке — твои действия? (сценарий log4shell)
Порядок: оценить, найти, закрыть окно, пропатчить, проверить. Оценить: читается advisory — условия эксплуатации, есть ли эксплойт в дикой природе, какие версии затронуты; log4shell был worst case — RCE одной строкой в любом логируемом поле. Найти: запрос к SBOM-базе или массовый скан (Trivy/Grype по всем образам в registry) — список сервисов с уязвимой версией, отсортированный по exposure: сначала то, что смотрит в интернет. Закрыть окно до патча: виртуальный патч на WAF (сигнатуры на паттерн атаки), отключение уязвимой функциональности флагом или конфигом (для log4shell — log4j2.formatMsgNoLookups=true), egress-фильтрация — RCE-цепочки почти всегда требуют исходящего соединения за пейлоадом, и закрытый egress ломает эксплуатацию. Пропатчить: массовые авто-PR с bump версии, приоритет по exposure, форсированный релизный поток — ради этого и держат быстрый пайплайн. Проверить: рескан, что уязвимых версий не осталось, и поиск признаков эксплуатации за прошедшее окно — логи, IoC, алерты, — потому что «мы пропатчились» и «нас не успели» — разные утверждения. Параллельно — коммуникация: статус-канал, чтобы сто человек не спрашивали «а нас касается?».
Отвечают только «обновить версию», пропуская окно между выходом CVE и патчем — а вопрос ровно про это окно: виртуальный патч, отключение функциональности, egress. И почти никто не вспоминает про ретроспективный поиск компрометации.
Follow-up интервьюера: апстрим ещё не выпустил фикс — что делать? — митигировать конфигом и периметром, изолировать сервис, в крайнем случае — форкнуть и пропатчить самим или выключить функциональность. «Ждать релиза» — не ответ при активной эксплуатации.
14. Какой должна быть политика обновления зависимостей?
Ключевой тезис: обновление зависимостей — это регулярный процесс, а не событие. Компании, которые обновляются раз в год «большим прыжком», получают худшее из двух миров: месяцы жизни с известными CVE плюс болезненный апгрейд через десять мажорных версий. Механика: Renovate или Dependabot открывают авто-PR на каждое обновление; патчи и минорные версии с зелёными тестами мержатся почти автоматически, мажорные — вручную с чтением changelog. Security-обновления — отдельный ускоренный поток: PR с фиксом CVE помечается и мержится в приоритете, SLA привязан к severity. Что делает эту машину безопасной: честное тестовое покрытие (авто-мерж без тестов — рулетка), lock-файлы (обновление — это явный диф, а не сюрприз при сборке) и группировка (Renovate умеет собирать мелочь в один PR в неделю, чтобы не хоронить команду под сотней PR). Тонкость, которую ценят: свежайшая версия — не всегда безопаснейшая; атаки через захваченные аккаунты мейнтейнеров прилетают именно в новых релизах, поэтому для несекьюрити-обновлений разумна выдержка в несколько дней (в Renovate — minimumReleaseAge), а security-фиксы едут сразу.
Две крайности: «обновляем всё автоматически» без слова про тесты и выдержку — и «обновляем только при CVE», что означает вечно устаревший стек и гигантский диф в момент, когда CVE всё-таки выйдет.
Follow-up интервьюера: зачем выдержка перед авто-мержем новых версий? — свежий релиз может оказаться скомпрометированным (захват аккаунта мейнтейнера): за несколько дней такие инциденты обычно вскрываются и версия отзывается.
Блок 3. Секреты
15. Почему секреты в git — до сих пор проблема №1 и как искать уже утёкшие?
Потому что git ничего не забывает. Секрет, закоммиченный и «удалённый следующим коммитом», живёт в истории вечно — и достаётся за секунды любым, у кого есть клон. Клонов больше, чем кажется: форки, зеркала, CI-кеши, ноутбуки уволившихся. Публичные репозитории сканируются ботами непрерывно: между пушем AWS-ключа на GitHub и первой попыткой его использовать проходят минуты. Масштаб проблемы стабилен год к году — отчёты сканеров находят миллионы новых секретов в публичных репозиториях ежегодно, и это только публичные. Искать утёкшее: gitleaks или trufflehog по всей истории всех репозиториев (gitleaks detect идёт по коммитам, а не по текущему срезу — это принципиально), trufflehog дополнительно умеет верифицировать находки — проверять, жив ли ключ, что радикально режет шум. Сканировать надо не только git: образы в registry (секреты запекают в слои), артефакты CI, вики и таск-трекеры. Найденное живое — сразу в процесс ротации: считается скомпрометированным с момента попадания в историю, независимо от того, «видел ли кто-то».
Предлагают «удалить коммит с секретом» как решение. История переписывается тяжело (filter-repo, force-push всем клонам), а главное — бессмысленно: секрет уже мог быть скопирован. Ротация первична, чистка истории — гигиена после.
Follow-up интервьюера: чем верифицированные находки trufflehog лучше регексов? — регекс находит строку, похожую на ключ; верификация проверяет ключ против API. Из тысячи «похожих» живых — десятки, и работать надо с ними.
16. Секрет утёк — что делать?
Первое действие — ротация, немедленно. Не разбор «кто видел», не удаление коммита — отзыв и перевыпуск: с момента утечки секрет считается скомпрометированным, и каждая минута его жизни — открытое окно. Дальше по порядку. Оценить blast radius: что этот секрет открывает — одну базу или админский доступ к облаку; для облачных ключей — какие permissions у роли. Проверить использование: логи аутентификации, CloudTrail/audit logs за весь период жизни секрета — искать доступы с незнакомых IP, в нерабочее время, к необычным ресурсам; факт утечки без следов использования и факт использования — два разных инцидента, второй эскалируется в полноценный incident response. Найти и обновить всех потребителей секрета — вот где мстит отсутствие централизованного управления: если секрет размазан по десяти конфигам, ротация превращается в квест с даунтаймом. Закрыть канал утечки: pre-commit-хуки, push protection, обучение. И записать в инцидент-лог с разбором: утечки повторяются там, где их разбирают шёпотом. Кандидату важно проговорить порядок: ротация до расследования, потому что расследование не мешает атакующему, а ротация — мешает.
Первым действием называют «удалить из истории git» или «выяснить, кто виноват». Пока переписывается история, ключ работает. Ротация — минуты; всё остальное — после.
Follow-up интервьюера: ротация этого секрета требует даунтайма — ротируем? — да, и это аргумент чинить архитектуру: секреты, ротация которых стоит даунтайма, — это долг, который вскрывается в худший момент.
17. Как не дать секретам попадать в git заранее?
Оборона в три эшелона, потому что любой одиночный слой протекает. Первый — рабочее место: pre-commit-хук с gitleaks режет коммит с секретом до того, как он стал историей. Честная оговорка: хук живёт на машине разработчика, ставится добровольно и обходится флагом --no-verify — это удобство, а не контроль. Второй — сервер: push protection (у GitHub — встроенная, самостоятельно — pre-receive-хуки или скан на PR, блокирующий мерж) — вот это уже контроль, обойти его локальным флагом нельзя. Третий — среда, в которой секретам просто не место в коде: шаблоны сервисов, где конфигурация читается из переменных окружения или Vault, .env в .gitignore с первого коммита плюс .env.example с пустыми значениями, секции в доке «как получить креды» вместо «спроси у Васи файлик». Четвёртый, страховочный — регулярный скан всех репозиториев по истории: ловит то, что просочилось до внедрения защиты или мимо неё. Метрика зрелости — время от попадания секрета в git до ротации; в хорошем сетапе это часы, потому что скан и алертинг автоматические.
Называют только pre-commit-хуки и считают вопрос закрытым. «А если разработчик хук не поставил или обошёл?» — тишина. Серверная защита обязательна именно потому, что клиентская — добровольная.
Follow-up интервьюера: push protection заблокировал пуш, разработчик уверен, что это false positive — процесс? — механизм обхода с обоснованием и алертом security-команде: блокировка без выхода учит людей маскировать секреты от регексов, это хуже.
18. Как устроен Vault?
HashiCorp Vault — централизованное хранилище секретов с API, аудитом и контролем доступа. Ключевые механики, которые спрашивают. Sealed/unsealed: данные Vault зашифрованы мастер-ключом, который при старте собирается из частей по схеме Шамира (например, 3 из 5 у разных людей) или через auto-unseal облачным KMS; запечатанный Vault не отдаёт ничего — это защита от кражи самого хранилища. Auth-методы: люди ходят через OIDC/LDAP, приложения — через Kubernetes auth (под предъявляет свой ServiceAccount-токен, Vault проверяет его у API-сервера), в облаке — через IAM; AppRole — для того, что не умеет лучше. Каждой аутентификации соответствует политика — path-based least privilege. Динамические секреты — главный козырь: Vault не хранит пароль от базы, а создаёт учётку на лету с TTL — истёк срок, учётка отозвана. Утечка такого секрета — окно в часы, а не в годы; плюс каждая копия секрета уникальна, видно, чья утекла. Всё пишется в audit log. Финальный акцент: Vault — не «база с паролями», а брокер короткоживущего доступа; кто описывает его как key-value с шифрованием, тот использовал десятую часть.
Рассказывают только про KV-хранение. Вопросы «что такое unseal и зачем» и «чем динамический секрет лучше статичного» отделяют тех, кто Vault эксплуатировал, от тех, кто читал лендинг.
Follow-up интервьюера: Vault упал — что с продом? — сервисы с полученными секретами живут до истечения TTL, новые поды секретов не получат. Поэтому Vault — tier-0 система: HA-кластер, автопилот распечатки, мониторинг и репетиция отказа.
19. OIDC-федерация в CI вместо статичных ключей — как это работает?
Классическая боль: в настройках CI лежит вечный облачный ключ, и кто угодно с доступом к пайплайну (или к взломанному CI — вспомни инциденты с CI-платформами) уносит его и пользуется откуда угодно. OIDC-федерация убирает сам предмет кражи. Механика: CI-платформа (GitHub Actions, GitLab) выпускает для каждой джобы короткоживущий подписанный JWT с клеймами — репозиторий, ветка, окружение, workflow. Облако настроено доверять этому issuer: IAM-роль разрешает AssumeRole только токенам с конкретными клеймами — например, «репозиторий org/app, ветка main». Джоба обменивает JWT на временные креды на минуты — и статичного секрета не существует вообще: нечего красть, нечего ротировать, нечего забывать в логах. Критичная деталь конфигурации — строгость условий на клеймы: доверять «любому репозиторию организации» — значит, что компрометация одного репозитория даёт роль всем; правильный trust policy пиннит репозиторий, ветку и окружение. Тот же паттерн работает с Vault (JWT-auth) и между облаками. База про то, где вообще жить секретам пайплайна, — в DevOps-подборке; OIDC — её взрослое продолжение.
Говорят «OIDC безопаснее» без механики: кто выпускает токен, что в клеймах, кто и что проверяет. И пропускают главную мину — широкие trust policy, где условием стоит вся организация вместо конкретного репозитория и ветки.
Follow-up интервьюера: чем JWT из CI отличается от того же статичного ключа, его же тоже можно перехватить? — временем жизни (минуты) и контекстом: токен выпускается под конкретную джобу и бесполезен вне её окна. Перехват возможен, персистентный доступ — нет.
20. Секреты в Kubernetes — почему base64 не защита и что делать?
Kubernetes Secret — это base64, то есть кодирование, а не шифрование: base64 -d — вся «криптография». Разница между Secret и ConfigMap — в обвязке, и она разобрана в DevOps-подборке; здесь — что с этим делать по-взрослому. Первое: encryption at rest в etcd — без него секреты лежат в etcd и его бэкапах открытым текстом, а бэкап etcd охраняют обычно куда хуже кластера; включается EncryptionConfiguration, правильный провайдер — KMS, чтобы ключ шифрования не лежал рядом с данными на том же диске. Второе: RBAC — право читать секреты выдаётся отдельно и скупо, get secrets кластерно — это почти админ. Третье: источник правды выносится наружу — External Secrets Operator синхронизирует секреты из Vault/облачных менеджеров в нативные Secret'ы (удобно, но копия живёт в etcd), либо Secrets Store CSI Driver монтирует их прямо в под, минуя etcd вообще. Четвёртое: доставка в под — файлом, а не env: переменные окружения утекают в kubectl describe, дампы процессов и дочерние процессы. И аудит: кто читал секреты — вопрос, на который должен отвечать audit log, а не пожатие плечами.
«У нас секреты в Kubernetes Secrets, значит защищено». Без encryption at rest и жёсткого RBAC это защита уровня «завёрнуто в газету». Про то, что env-переменные хуже файлов, не знает большинство.
Follow-up интервьюера: ESO или CSI-драйвер — что выбрать? — CSI строже (секрет не касается etcd), но секрет живёт только в поде; ESO даёт нативные Secret'ы для совместимости со всем экосистемным. Выбор — компромисс строгости и удобства.
21. Ротация и короткоживущие креды — почему это норма, а не паранойя?
Потому что ротация — это признание реальности: секреты утекают, и вопрос не «если», а «на сколько открыто окно». Статичный ключ, живущий три года, означает, что любая его утечка за три года — где-то в логе, бэкапе, ноутбуке, гите — даёт рабочий доступ сегодня. Короткий TTL превращает ту же утечку в тыкву. Иерархия зрелости: ручная ротация по регламенту (уже лучше, чем никогда, но её саботирует страх «что-нибудь отвалится») → автоматическая ротация статичных секретов (секрет-менеджер перевыпускает, потребители перечитывают) → короткоживущие креды по умолчанию: динамические секреты Vault, временные облачные креды через STS/OIDC, короткие TLS-сертификаты от cert-manager, токены ServiceAccount с audience и сроком. Важный инженерный сдвиг: ротация должна быть спроектирована, а не прикручена — приложения перечитывают секреты без рестарта или переживают рестарт незаметно, и есть период двух активных версий секрета, чтобы смена не была моментом даунтайма. Лакмус зрелости, который любят на собесах: «страшно ли вам ротировать любой секрет прямо сейчас?» Если страшно — ротации нет, есть регламент на бумаге.
Соглашаются «ротация нужна», но на вопрос «почему у вас ключ жил два года» отвечают «боялись сломать». Это и есть диагноз: систему, в которой ротация опасна, чинят архитектурно, а не откладыванием.
Follow-up интервьюера: как ротировать секрет без даунтайма? — двухфазно: выпустить новую версию, переключить потребителей (обе версии валидны в окне перехода), отозвать старую. Grace-период — обязательная часть дизайна.
Блок 4. Контейнеры и образы
22. Чем контейнер опасен по умолчанию?
Тем, что это не песочница, а процесс на общем ядре с опциональной изоляцией. Главные следствия. Общее ядро: уязвимость ядра хоста пробивается из любого контейнера — гипервизора между ними нет, и «контейнерная изоляция» заканчивается там, где начинается kernel exploit. Root по умолчанию: процессы в контейнере работают от uid 0, и без user namespaces это тот же uid 0, что у root на хосте; вся разница — в отобранных capabilities и профилях, то есть в настройках, которые можно ослабить одним флагом. Побег из контейнера при таком раскладе — не «выход из виртуалки», а короткий шаг: root в контейнере плюс любой канал к хосту (примонтированный Docker socket, hostPath, privileged-режим) — и атакующий на хосте. Дальше — дефолты помягче: плоская сеть между контейнерами, писабельная файловая система, отсутствие лимитов, если их не задали. Правильная рамка ответа: контейнер по умолчанию оптимизирован под удобство разработки, а не под изоляцию недоверенного кода; безопасным его делает стопка осознанных ограничений — non-root, дроп capabilities, seccomp, read-only, политики, — и каждый следующий вопрос блока будет про одно из них.
«Контейнеры изолированы, значит безопасны». Вопрос «root в контейнере — это root на хосте?» разделяет аудиторию: правильный ответ — «по умолчанию почти да, спасают только снятые capabilities и user namespaces, если они включены».
Follow-up интервьюера: когда контейнеров недостаточно и нужен другой класс изоляции? — недоверенный код и жёсткая мультитенантность: gVisor, Kata, Firecracker — контейнерный UX с изоляцией уровня VM.
23. Зачем минимальные базовые образы — alpine, distroless?
Три причины: поверхность атаки, число CVE, скорость. Поверхность: полный дистрибутив в образе — это шелл, пакетный менеджер, curl, компиляторы. Для приложения они не нужны, для атакующего после RCE — это готовый набор инструментов: скачать пейлоад, закрепиться, разведать сеть. В distroless-образе нет даже шелла — эксплуатация не останавливается полностью, но дорожает резко. CVE: сканер считает уязвимости всех пакетов образа; сотни пакетов Ubuntu-образа генерируют постоянный поток находок, которые кто-то должен триажить, — минимальный образ сокращает этот шум в разы не потому, что «спрятал» уязвимости, а потому что их носителей физически нет. Скорость: меньше образ — быстрее pull, деплой и автоскейлинг. Практика: статические бинарники (Go, Rust) — scratch или distroless/static; интерпретируемые — соответствующий distroless или slim-вариант; alpine компактен, но musl вместо glibc иногда стреляет совместимостью — это стоит назвать, чтобы показать практику. Сборка через multi-stage: компиляторы живут в builder-стадии, в прод едет только артефакт. Дебаг без шелла — через ephemeral containers, и это решённая проблема, а не аргумент против.
Называют только размер. Security-аргумент — отсутствие инструментов для пост-эксплуатации и кратно меньший поток CVE — и есть суть; «маленький образ» без него звучит как оптимизация трафика.
Follow-up интервьюера: distroless без шелла — как дебажить в проде? — kubectl debug с ephemeral-контейнером: тулинг приезжает на время дебага и не живёт в образе постоянно.
24. Сканирование образов в CI — как построить правильно?
Trivy — рабочий стандарт: бесплатный, быстрый, кроме образа сканирует файловую систему и конфиги. Минимальный полезный шаг в CI:
# .gitlab-ci.yml
image_scan:
stage: test
script:
# уязвимости в коде и lock-файлах — до сборки
- trivy fs --exit-code 1 --severity CRITICAL,HIGH --ignore-unfixed .
# собранный образ: пакеты ОС + зависимости
- trivy image --exit-code 1 --severity CRITICAL,HIGH
--ignore-unfixed $IMAGE_TAG
# IaC и Dockerfile: misconfiguration
- trivy config --exit-code 1 .
Ключевые решения, которые проверяют на собесе. --ignore-unfixed: блокировать пайплайн CVE, для которой нет патча, бессмысленно — разработчик не может ничего сделать; такие находки идут в отчёт и vulnerability management, а не в красный крест на PR. Severity gate: блокируют critical и high, medium/low — отчётом. Baseline через .trivyignore с комментариями и сроками — для осознанных исключений. И второй контур, о котором забывают: registry сканируется по расписанию, потому что образ, чистый на момент сборки, через месяц содержит свежеопубликованные CVE — сканирование только в CI видит образы лишь в момент рождения.
Ставят скан только в CI и считают тему закрытой. «Образ собран полгода назад и крутится в проде — кто найдёт в нём новую CVE?» — никто, если нет периодического скана registry или кластера.
Follow-up интервьюера: почему --ignore-unfixed — не заметание под ковёр? — потому что unfixed-находки не исчезают, а меняют маршрут: в систему управления уязвимостями с трекингом до выхода патча. Блокировка PR — инструмент для действий, доступных разработчику.
25. Подпись и верификация образов — cosign и sigstore
Проблема: тег в registry мутабелен, и «мы деплоим то, что собрали» — вера, а не факт. Между сборкой и деплоем образ может быть подменён: скомпрометированный registry, украденный push-токен, злонамеренный инсайдер. Подпись делает происхождение проверяемым: cosign подписывает digest образа, подпись кладётся в тот же registry рядом. Sigstore-стек решает вечную боль подписей — управление ключами — через keyless-режим: подписант аутентифицируется через OIDC (в CI — тот же workload-токен), получает короткоживущий сертификат от Fulcio, факт подписи записывается в публичный журнал прозрачности Rekor. Ключа, который можно украсть или потерять, не существует; подпись говорит «этот образ подписал workflow такого-то репозитория на такой-то ветке». Вторая половина, без которой первая бессмысленна, — верификация при деплое: admission-контроллер (Kyverno verifyImages или sigstore policy-controller) проверяет подпись и identity подписанта и отклоняет неподписанное. Тем же механизмом подписываются аттестации — SBOM и provenance (cosign attest), что подводит к SLSA. Подпись без принудительной верификации — украшение: подписывать должны все пайплайны, а кластер — отказываться от всего остального.
Рассказывают про «подписываем образы» и замолкают. Вопрос «а кто и где проверяет?» вскрывает картонность: без admission-верификации подписанный и неподписанный образ деплоятся одинаково.
Follow-up интервьюера: что именно подписывается — тег? — digest: подпись привязана к содержимому, перевесить тег на другой образ можно, подпись за ним не поедет. Поэтому и деплой — по digest.
26. Rootless-контейнеры и USER в Dockerfile — в чём разница и что обязательно?
Два разных уровня, которые постоянно смешивают. USER в Dockerfile — от кого работает процесс внутри контейнера: создаёшь пользователя и переключаешься (USER 10001), процесс больше не uid 0, и большинство эксплойтов пост-эксплуатации теряют опору — нельзя ставить пакеты, писать в системные пути, биндить привилегированные порты. Это гигиенический минимум для каждого прод-образа, усиленный на уровне оркестратора: runAsNonRoot: true в securityContext заставляет kubelet отказаться запускать контейнер, если тот претендует на root, — защита от забытого USER. Rootless-контейнеры — другое: сам рантайм (dockerd/containerd/podman) работает от обычного пользователя хоста, и через user namespaces uid 0 контейнера отображается в непривилегированный uid хоста. Это защита от компрометации демона и побегов: даже вырвавшись, атакующий оказывается на хосте никем. Цена rootless — ограничения с сетью, портами ниже 1024 и некоторыми стораджами. Приоритет внедрения честный: non-root внутри контейнера — обязательная база везде; rootless-рантайм — усиление для сред с повышенными требованиями и CI-раннеров, которые гоняют чужой код.
На «что такое rootless» отвечают про USER в Dockerfile. Это маркер: кандидат не различает привилегии процесса в контейнере и привилегии рантайма на хосте — а это два независимых слоя защиты.
Follow-up интервьюера: приложение слушает 80-й порт и не стартует под non-root — что делать? — слушать 8080 и маппить снаружи (Service это делает бесплатно) или дать бинарю NET_BIND_SERVICE. Возвращать root ради порта — капитуляция.
27. Linux capabilities — что дропать и что такое no-new-privileges?
Capabilities — это root, распиленный на десятки отдельных привилегий: NET_ADMIN — рулить сетью, SYS_ADMIN — почти всё (её называют «новый root»), NET_BIND_SERVICE — порты ниже 1024, CHOWN, SETUID и так далее. Docker по умолчанию выдаёт контейнеру набор из примерно полутора десятков — меньше полного root, но всё ещё щедро: типовому веб-приложению не нужна ни одна. Правильный паттерн — белый список: drop: ["ALL"], дальше добавлять по одной с обоснованием в ревью. Это резко ограничивает пост-эксплуатацию: RCE в приложении без capabilities не может перенастроить сеть, смонтировать файловую систему, трассировать чужие процессы. no-new-privileges (в Kubernetes — allowPrivilegeEscalation: false) — второй замок: запрещает процессу получать привилегии сверх текущих любым способом, главный из которых — setuid-бинарники: с этим флагом sudo и его родня превращаются в обычные файлы. Вместе с non-root это фундамент restricted-профиля Pod Security: не root, эскалация запрещена, capabilities сброшены. Стоимость внедрения около нуля — подавляющее большинство приложений не заметит, — а класс закрываемых атак заметный, поэтому отговорки «потом настроим» тут не принимаются.
Не могут назвать ни одной capability и зачем она. Достаточно трёх: SYS_ADMIN — почти root и не должна встречаться в аппликейшн-подах, NET_ADMIN — сеть, NET_BIND_SERVICE — легитимный кейс для 80-го порта.
Follow-up интервьюера: кому в кластере всё-таки нужны богатые capabilities? — системным агентам: CNI, CSI, мониторингу узла. Их выделяют в отдельные namespace с privileged-профилем — и это осознанное исключение, а не дефолт.
28. Seccomp и AppArmor — зачем и как включать?
Seccomp фильтрует системные вызовы: приложению из трёх с лишним сотен syscalls Linux реально нужны десятки, всё остальное — поверхность для kernel-эксплойтов. Профиль RuntimeDefault (собранный рантаймами список, блокирующий опасное: mount, ptrace, загрузку модулей ядра) стоит почти ничего и обязателен для restricted-профиля Pod Security. AppArmor (или SELinux в RHEL-мире) — mandatory access control поверх: ограничивает процессу файлы, сеть, capabilities по профилю. Рабочий securityContext пода, собирающий блок воедино:
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: registry.local/app@sha256:abc123...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
Это и есть «безопасный под по умолчанию» — шаблон, который должен лежать в каждом Helm-чарте компании. Кастомные seccomp-профили под конкретное приложение — следующий уровень: точнее, но требуют профилирования и поддержки; начинать надо не с них, а с повсеместного RuntimeDefault.
Считают seccomp экзотикой «для параноиков» и не знают, что RuntimeDefault — требование restricted-уровня PSA. Вопрос «что сломается от включения RuntimeDefault?» имеет ответ «почти ничего» — и незнание этого выдаёт, что кандидат не пробовал.
Follow-up интервьюера: чем seccomp отличается от capabilities, они же оба «ограничивают»? — осью: capabilities решают, какие привилегированные действия доступны, seccomp — какие syscalls вообще можно позвать. Непривилегированный syscall с багом ядра capabilities не остановят, seccomp — да.
29. Read-only rootfs — почему это дёшево и полезно?
readOnlyRootFilesystem: true монтирует корневую файловую систему контейнера только на чтение. Что это ломает атакующему: классическая пост-эксплуатация начинается с записи — скачать пейлоад, подменить бинарь или конфиг, положить веб-шелл, закрепиться. На read-only корне всё это упирается в «Read-only file system» — атака не умирает полностью, но лишается самых наезженных дорожек, а попытки записи становятся громким сигналом для runtime-детекта. Что это стоит: почти ничего, и в этом пуанта. Контейнер и так должен быть иммутабельным — образ собран, конфигурация снаружи, состояние в базах и volume'ах; если приложению нужно писать во временные файлы, точечно подмонтируется emptyDir в /tmp или конкретный каталог кеша. Включение read-only — это один флаг плюс явная инвентаризация мест записи, которая сама по себе полезна: внезапно выясняется, что приложение пишет в /app/logs вместо stdout, и это чинится. Побочный бонус — дисциплина: конфиг-дрифт внутри контейнера становится невозможен физически. Из всех харденинг-мер у read-only rootfs лучшее соотношение «цена/эффект», поэтому на собесе она — маркер практического, а не бумажного харденинга.
«Приложению же надо писать файлы» — как аргумент против. Ответ-паттерн: корень read-only, записываемые точки — явные tmpfs/emptyDir-маунты. Кто это знает — включал; кто нет — рассуждает теоретически.
Follow-up интервьюера: как найти все места, куда приложение пишет, до включения? — прогнать под нагрузкой с аудитом записи (strace/fanotify/Falco-правило на write вне разрешённых путей) или просто включить в staging и собрать ошибки — они честные.
Блок 5. Kubernetes security
30. RBAC по least privilege — где чаще всего дыры?
Механика RBAC — роли, биндинги, отсутствие запрещающих правил — разобрана в DevOps-подборке; DevSecOps-собес интересуют типовые дыры. Первая — cluster-admin у CI: деплой-пайплайну выдали всё, потому что «так проще», и теперь компрометация CI равна компрометации кластера; правильный масштаб — роль на конкретные ресурсы в конкретных namespace. Вторая — wildcard: verbs: ["*"] или resources: ["*"] в ролях — мина, которая расширяется сама: новые типы ресурсов автоматически попадают под старую звёздочку. Третья — default ServiceAccount с автоматически смонтированным токеном в каждом поде: любое RCE в приложении получает бесплатный доступ к API. Четвёртая — небезопасные глаголы, которые выглядят безобидно: create pods — это возможность запустить под с hostPath и SA-токеном; create pods/exec — вход в чужие контейнеры; право читать секреты namespace — часто весь namespace и есть. Аудит: kubectl auth can-i --list --as= по ключевым субъектам, автоматом — инструменты типа rbac-tool или регулярные политики-проверки. Правило: роли пишутся от задач субъекта, а не от «чтобы работало», и ревьюятся как код.
Рассказывают устройство RBAC, но не могут назвать ни одной конкретной дыры. «Что плохого в create pods?» — контрольный вопрос: кто не видит в нём эскалации через hostPath и чужие ServiceAccount, тот RBAC-аудит не делал.
Follow-up интервьюера: как найти, у кого в кластере фактический cluster-admin? — перечислить не только явные биндинги на cluster-admin, но и эквиваленты: wildcard-роли, право escalate/bind, право писать в RoleBinding'и — эскалация прячется в них.
31. ServiceAccount-токены — что с ними не так по умолчанию?
По умолчанию каждый под получает смонтированный токен своего ServiceAccount — даже если приложение в жизни не ходило в Kubernetes API. Для атакующего это подарок: RCE в любом поде автоматически даёт аутентифицированный доступ к API-серверу, и дальше вопрос только в том, что разрешено этому SA (а с учётом дыр из прошлого вопроса — часто немало). Гигиена: automountServiceAccountToken: false на уровне ServiceAccount или пода для всех, кому API не нужен, — то есть для подавляющего большинства прикладных подов; включать обратно — точечно и осознанно. Второй пласт — свойства самих токенов: legacy-токены из Secret'ов были вечными и без привязки к аудитории; современные projected-токены выпускаются с TTL, аудиторией и привязкой к поду — умер под, умер токен. Убедиться, что в кластере не живут вечные Secret-токены, созданные «для интеграций» много лет назад, — отдельный пункт аудита: такие токены переживают всё и всплывают в утечках. Третий пласт — использование SA-токенов как OIDC-identity для внешних систем (Vault kubernetes-auth, облачные федерации): правильный паттерн, но с той же дисциплиной — короткие TTL, узкие аудитории.
Не знают, что токен монтируется по умолчанию всем. Вопрос «что получит атакующий после RCE в вашем самом скучном поде?» приводит к неудобному ответу «аутентифицированный доступ к API-серверу», и кандидат должен дойти до него сам.
Follow-up интервьюера: как найти поды, которым токен реально нужен? — по факту использования: audit log API-сервера покажет, какие SA ходят в API; остальным — отключать монтирование смело.
32. Pod Security Admission — уровни, режимы и чем он заменил PSP
PSA — встроенный admission-контроллер, пришедший на смену выпиленным PodSecurityPolicy: PSP были мощными, но непредсказуемыми (мутировали поды, порядок применения политик был лотереей), PSA проще и декларативнее — только проверка, никаких мутаций. Три уровня-профиля: privileged — без ограничений (для системных namespace), baseline — отсекает известные опасности (privileged-контейнеры, hostPath, hostNetwork, добавление capabilities сверх дефолта), restricted — жёсткий харденинг: non-root, drop ALL, seccomp RuntimeDefault, запрет эскалации. Три режима: enforce блокирует, audit пишет в audit log, warn ругается в ответе kubectl. Настраивается лейблами namespace:
apiVersion: v1
kind: Namespace
metadata:
name: prod-app
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Это и есть стратегия внедрения в одном манифесте: enforce на достижимом уровне, audit/warn на целевом — команды видят, что сломается при ужесточении, до того, как оно сломается. Ограничение PSA, которое надо назвать: профили фиксированные, кастомную логику («только образы из нашего registry») он не умеет — для этого Kyverno или Gatekeeper.
Путают уровни с режимами: «enforce restricted» — это режим плюс профиль, а кандидаты называют их вперемешку. И не знают паттерн «enforce baseline, warn restricted» — а это главный практический приём внедрения без пожара.
Follow-up интервьюера: почему PSP вообще выпилили? — мутации подов, неочевидный выбор политики через RBAC и невозможность dry-run: политику нельзя было безопасно проверить до включения. PSA спроектирован от этих ошибок.
33. NetworkPolicy: default-deny и сегментация east-west
Дефолт Kubernetes — плоская сеть: любой под ходит к любому, и после компрометации одного пода атакующий свободно сканирует весь кластер — это и есть east-west-движение, главный маршрут развития атаки. Синтаксис политик и грабли с CNI разобраны в DevOps-подборке; security-вопрос — про стратегию. База: default-deny на ingress и egress в каждом прикладном namespace, дальше — явные разрешения по принципу «кто с кем реально разговаривает»: фронт → бэк по 8080, бэк → база по 5432, все → DNS. Egress-политики важны не меньше ingress, хотя их делают в десять раз реже: закрытый egress ломает эксплуатационные цепочки — скачивание пейлоада, reverse shell, эксфильтрацию, обращение к облачному metadata-сервису. Процессно: политики живут рядом с приложением в его чарте (команда описывает свои потоки), а платформа держит гардрейл — namespace без default-deny не проходит admission-политику. Честные ограничения, которые стоит назвать: NetworkPolicy оперирует L3/L4 — «какой под к какому по какому порту», без L7 и без шифрования; identity-политики уровня «сервис A может звать метод B» и mTLS — этаж выше, это service mesh или Cilium с его расширениями.
Пишут ingress-политики и считают сегментацию готовой. «А что у вас с egress?» — тишина. Между тем именно egress-deny останавливает большинство реальных пост-эксплуатационных сценариев: без исходящих соединений атакующему нечем работать.
Follow-up интервьюера: как ввести default-deny в живом кластере и ничего не уронить? — сначала наблюдение: карта реальных потоков из CNI-телеметрии (Hubble, flow logs), генерация политик по ней, обкатка в audit-подобном режиме, потом enforcement по namespace за namespace.
34. Admission-политики: OPA Gatekeeper против Kyverno — когда что?
Оба решают одну задачу — программируемый контроль того, что попадает в кластер, там, где встроенного PSA не хватает: «образы только из корпоративного registry», «у каждого Deployment есть лимиты и владелец в лейблах», «Ingress без TLS запрещён». Gatekeeper — это OPA в Kubernetes: политики пишутся на Rego, языке общего назначения для политик. Плюсы — выразительность и переносимость (тот же Rego проверяет Terraform-планы и JSON в CI), минус — Rego надо учить, и порог входа реален. Kyverno — Kubernetes-native: политики описываются YAML-манифестами, похожими на сами ресурсы, — команда, которая умеет в Kubernetes, пишет политики сразу. Плюс Kyverno умеет не только валидировать, но и мутировать (дописывать дефолты) и генерировать ресурсы (default-deny NetworkPolicy в каждый новый namespace — автоматически), а verifyImages закрывает проверку подписей cosign из коробки. Типовая политика:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-registry
spec:
validationFailureAction: Enforce
rules:
- name: allowed-registries
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "Образы только из registry.company.ru"
pattern:
spec:
containers:
- image: "registry.company.ru/*"
Выбор честный: платформенная команда с политиками за пределами Kubernetes — Gatekeeper; команда, живущая в YAML и хотящая результат завтра, — Kyverno. Обоим обязателен audit-режим до enforcement.
Называют оба инструмента, но не могут написать ни одной политики и не знают, что Kyverno умеет мутацию и генерацию — а это половина его ценности. «Перечислил названия» и «внедрял» звучат по-разному.
Follow-up интервьюера: admission-контроллер упал — что с кластером? — зависит от failurePolicy вебхука: Fail — деплои встали (безопасно, но больно), Ignore — политики не проверяются (тихо и опасно). Это осознанный выбор плюс HA самого контроллера.
35. Falco — что такое runtime-детект и что он ловит?
Всё предыдущее — превентивные меры, а Falco отвечает на вопрос «а что происходит прямо сейчас»: он смотрит системные вызовы (через современный eBPF-пробник или модуль ядра) и матчит их против правил поведения. Классика из коробки: шелл, запущенный в контейнере (Terminal shell in container) — контейнеру прода незачем интерактивный bash; чтение чувствительных файлов — /etc/shadow, приватные ключи; запись в системные каталоги; неожиданный исходящий коннект от процесса, который никогда не ходил в сеть; запуск бинарей, которых не было в образе, — почти наверняка скачанный пейлоад. Ценность runtime-слоя в том, что он ловит эксплуатацию неизвестных дыр: сканеры ищут известные CVE, а Falco видит сам факт «в контейнере nginx кто-то запустил curl на незнакомый IP» — независимо от того, через какую уязвимость туда зашли. Инженерная часть: правила тюнятся под среду (дефолтный набор шумит на легитимных операциях — миграции, дебаг), события уезжают в SIEM/алертинг через Falcosidekick, а реакция — заранее описанный плейбук: какой алерт — пейдж, какой — тикет. Falco без процесса реагирования — регистратор, который смотрит, как тебя грабят, в отличном разрешении.
Описывают Falco как «антивирус для Kubernetes» и не могут назвать ни одного конкретного правила. Три примера — шелл в контейнере, чтение /etc/shadow, неожиданный egress — минимальный набор, который показывает, что инструмент видели.
Follow-up интервьюера: Falco сработал: shell в prod-контейнере — твои действия? — по плейбуку: подтвердить (кто, каким процессом, что делал дальше), изолировать под NetworkPolicy/cordon вместо мгновенного kill — сохранить форензику, снять дамп и слепок, потом убивать и разбирать вектор.
36. Encryption at rest для etcd и audit logs API-сервера — зачем оба?
Это два разных вопроса безопасности control plane: «что если украдут данные» и «кто что делал». Encryption at rest: по умолчанию etcd хранит всё, включая Secret'ы, открытым текстом — доступ к файлам etcd или его бэкапу равен доступу ко всем секретам кластера, а бэкапы традиционно охраняются хуже живой системы. Включается через EncryptionConfiguration на API-сервере; провайдер aescbc шифрует, но держит ключ в конфиге на том же хосте — от кражи диска спасает, от компрометации ноды нет; взрослый вариант — kms, где ключи живут во внешнем KMS с собственным аудитом и ротацией. После включения — перезаписать существующие секреты, шифрование применяется при записи. Audit logs: API-сервер умеет журналировать каждый запрос — кто, что, когда, с какими параметрами и результатом. Без audit policy расследование инцидента в кластере — гадание; с ним — «SA такой-то читал секреты такие-то в 03:14». Политика настраивается по уровням (Metadata/Request/RequestResponse) с фокусом на чувствительном: секреты, RBAC-изменения, exec в поды; логи уезжают за пределы кластера — журнал, который атакующий может подтереть, не журнал. Вместе это база форензики: шифрование ограничивает ущерб кражи, аудит делает действия видимыми.
Уверены, что «Kubernetes же шифрует секреты сам». Не шифрует, пока не настроили. Второй провал — audit log включён, но пишется на диск мастера и никуда не отправляется: атакующий с доступом к ноде чистит его первым делом.
Follow-up интервьюера: почему aescbc-провайдер — полумера? — ключ лежит в конфиге API-сервера: кто скомпрометировал control plane ноду, тот получил и шифротекст, и ключ. KMS выносит ключ наружу и добавляет аудит обращений к нему.
37. Container escape — какие векторы и как закрывать?
Побег — переход из контейнера на хост, и большинство реальных побегов эксплуатируют не 0-day ядра, а щедрую конфигурацию. Векторы по частоте. privileged: true — не «чуть больше прав», а выключенная изоляция: все capabilities, все устройства хоста; побег отсюда — штатная процедура (примонтировать диск хоста и пожалуйста). hostPath на чувствительные пути — маунт /, /etc, /var/lib/kubelet — прямая запись в хост: cron, ssh-ключи, kubeconfig. Docker socket в контейнере (/var/run/docker.sock) — любимый паттерн CI: кто говорит с демоном, тот запускает privileged-контейнеры, конец истории. hostPID — видимость процессов хоста плюс с capability SYS_PTRACE — вход в них; hostNetwork — сетевой стек хоста и доступ к локальным сервисам вроде kubelet API. И только потом — честные уязвимости ядра и рантайма (истории вроде Dirty Pipe и runc CVE-2019-5736), против которых работают патчинг, seccomp и user namespaces. Закрытие — эшелонами: PSA baseline/restricted блокирует всё перечисленное декларативно; admission-политики добавляют точечные запреты (Docker socket, конкретные hostPath); для CI-сборок — rootless BuildKit/kaniko вместо проброса сокета; runtime-детект ловит попытки. Ответ строится от конфигурации к эксплойтам, не наоборот: параноить про 0-day, раздавая privileged, — любимое противоречие индустрии.
На «как сбежать из контейнера» начинают про уязвимости ядра, забыв privileged, hostPath и Docker socket — а 90% реальных побегов именно там. Интервьюер проверяет приоритеты, а не эрудицию про CVE.
Follow-up интервьюера: команде «нужен» Docker socket для сборки образов в CI — альтернативы? — kaniko, BuildKit rootless, buildah: сборка без демона и без привилегий. «Нужен сокет» в 2026-м почти всегда означает «не смотрели альтернативы».
38. Получил кластер в наследство — что проверить первым?
Чеклист по убыванию ущерба. Доступ снаружи: не торчит ли API-сервер в интернет без ограничений, нет ли публичных дашбордов и kubelet-портов; заодно — версия Kubernetes и давность патчей. Кто админ: перечислить cluster-admin и эквиваленты (wildcard-роли, право писать биндинги), особенно у ServiceAccount'ов — CI с cluster-admin находится этим запросом в первые пять минут. Секреты: включён ли encryption at rest, кто умеет читать секреты, нет ли вечных legacy-токенов SA. Рабочие нагрузки: privileged-поды и hostPath-маунты вне системных namespace (kubectl get pods -A -o json плюс jq — карта нарушений за минуту), automount токенов, образы по мутабельным тегам и из чужих registry. Политики: есть ли вообще PSA-лейблы на namespace, admission-контроллеры, NetworkPolicy (namespace без единой политики — плоская сеть). Наблюдаемость: пишется ли audit log и куда, есть ли runtime-детект. Плюс бэкап etcd и его защищённость. Результат — не героический ремонт всего сразу, а ранжированный список рисков с быстрыми победами: закрыть публичное, отобрать лишние cluster-admin, включить audit — за первую неделю; PSA и NetworkPolicy — планом по namespace. Вопрос проверяет способность приоритизировать, и хаотичный вывал всех знаний — сам по себе провал.
Начинают с экзотики («проверю seccomp-профили»), не спросив, торчит ли API-сервер наружу и у кого cluster-admin. Порядок — и есть ответ: сначала то, что эксплуатируется из интернета за час, потом харденинг.
Follow-up интервьюера: одна команда на «сколько privileged-подов в кластере»? — kubectl get pods -A -o jsonpath по securityContext.privileged или готовые сканеры среды — kube-bench по CIS-бенчмарку и kubescape дают такую картину пакетом.
Блок 6. CI/CD и supply chain
39. Какие угрозы у самого пайплайна?
Ключевая мысль, с которой начинается ответ: CI-раннер — это удалённое выполнение кода как сервис. Любой, кто может заставить пайплайн выполнить свою джобу, выполняет произвольный код в окружении, где лежат секреты деплоя, доступ к registry и часто к кластеру. Отсюда карта угроз. Кто может запускать джобы: право открыть PR или пушнуть ветку — это уже право исполнить код на раннере; в публичных репозиториях это буквально весь интернет. Что видит джоба: если секреты доступны любой джобе любой ветки — их унесёт первый же вредоносный PR; отсюда разделение секретов по окружениям и protected-веткам. Сам раннер: общие раннеры без изоляции между джобами означают, что одна джоба может отравить кеш, докер-слои или файловую систему для следующих; лечится эфемерными раннерами — окружение живёт одну джобу и умирает. Конфигурация пайплайна: тот, кто может править CI-конфиг, может добавить exfiltration-шаг — значит, конфиг ревьюится как код, а критичные шаблоны защищены от переопределения. Зависимости пайплайна: экшены, плагины, базовые образы сборки — тот же supply chain. Рамка для собеса: пайплайн — такой же прод, как прод, только с ключами от прода.
Рассуждают о безопасности того, что пайплайн собирает, а не самого пайплайна. Фраза-маркер зрелости — «раннер это RCE by design»; кто её не проговаривает, тот угрозу CI недооценивает системно.
Follow-up интервьюера: чем эфемерный раннер лучше постоянного? — нет накопления: секретов в истории, отравленного кеша, чужих артефактов. Каждая джоба — чистый лист, компрометация не переживает джобу.
40. Protected branches и обязательные ревью — от чего это защищает на самом деле?
Не только от кривого кода — от одностороннего изменения того, что едет в прод. Ветка, из которой деплоится прод, — граница доверия: всё, что в неё попало, будет исполнено с прод-привилегиями. Protected branch закрывает пути в обход: прямой пуш запрещён (в том числе админам — «включая администраторов» это чекбокс, о котором забывают), force-push и удаление ветки запрещены, вход — только через PR с обязательными условиями: минимум одно независимое ревью (для критичных репозиториев — два), зелёные обязательные проверки, актуальность ветки. Тонкости, на которых проверяют практику: ревью сбрасывается при новых коммитах — иначе схема «одобрили, потом дописал» легализует что угодно; CODEOWNERS требует ревью владельцев для чувствительных путей — CI-конфиги, Dockerfile, IaC, политики; статусы-проверки защищены от подмены. Отдельно — угроза инсайдера и скомпрометированного аккаунта: обязательное независимое ревью означает, что один захваченный аккаунт не может доставить код в прод, нужно два, — это уже другой класс атаки. Плюс подписанные коммиты и запрет на self-approve. Всё это — не бюрократия, а криптографическая по духу идея: изменение прода требует кворума.
Называют protected branches «процессом код-ревью». Security-смысл — кворум на изменение прода и отсечение путей в обход — формулируют единицы. «А админ может пушнуть напрямую?» — вопрос, на котором сыпется дефолтная настройка.
Follow-up интервьюера: ревью обязательное, но ревьюят не глядя — что делать технически? — сузить, что требует внимательного ревью: CODEOWNERS на критичные пути, автомерж для тривиального (bump зависимостей с зелёными тестами), чтобы человеческое внимание тратилось там, где нужно.
41. Почему PR из форков опасны и что такое pull_request_target?
PR из форка — это код незнакомца, который просит ваш CI его исполнить. Дефолтная защита GitHub Actions разумна: событие pull_request для форков запускается без секретов и с read-only токеном — вредоносный PR может жечь минуты раннера, но не может ничего унести. Проблемы начинаются, когда мейнтейнерам нужно больше — например, комментировать PR или деплоить превью, — и они переключаются на pull_request_target: он запускается в контексте базового репозитория, с секретами и токеном на запись. Само по себе это безопасно, пока workflow не трогает код из PR. Классическая дыра: workflow на pull_request_target делает checkout головы PR и запускает npm install или билд — и вот уже код атакующего исполняется с секретами репозитория; через этот паттерн обносили и большие проекты. Правила: pull_request_target не чекаутит и не исполняет код PR (только метаданные); если исполнение чужого кода необходимо — двухфазная схема: первый workflow без привилегий собирает артефакты, второй, привилегированный, работает только с результатами; лейбл-гейт «безопасно после ревью» для запуска тяжёлых проверок. Общий принцип шире GitHub: любой CI обязан различать «код доверенной ветки» и «код из внешнего мира» и не выдавать второму секреты.
Не видят разницы между pull_request и pull_request_target — а это буквально граница между «песочница» и «полные секреты». Кто говорит «форки безопасны, GitHub же защищает», не в курсе, что защиту снимают своими руками ради удобства ботов.
Follow-up интервьюера: нужно прогонять тесты форк-PR с секретом (интеграционный стенд) — как? — не давать секрет тестам напрямую: мок/стаб на PR, а интеграционный прогон — после аппрува мейнтейнером через лейбл, на эфемерном стенде с одноразовыми кредами минимальных прав.
42. SLSA — объясни уровни на пальцах
SLSA (Supply-chain Levels for Software Artifacts) — фреймворк, отвечающий на вопрос «насколько можно доверять происхождению артефакта» ступенями, по нарастанию гарантий. Уровень 0 — никаких: собрано где-то как-то. Уровень 1 — есть provenance: машиночитаемая декларация «этот артефакт собран из такого-то репозитория таким-то процессом»; подделать можно, но хотя бы появилась прослеживаемость. Уровень 2 — сборка на хостируемой платформе, и provenance подписан самой платформой: разработчик или атакующий с его правами уже не может сфабриковать происхождение — подпись ставит CI-система, а не человек. Уровень 3 — харденинг самой сборки: изоляция между сборками (одна джоба не влияет на другую), ключи подписи недоступны исполняемым шагам сборки, защита от вмешательства в процесс. Смысловая шкала простая: L1 — «мы записали, откуда это», L2 — «записи нельзя подделать снаружи сборки», L3 — «и изнутри сборки тоже». Практика: GitHub Actions с официальным генератором provenance и cosign-подписью даёт L2 и дорогу к L3 малой кровью; потребление — верификация provenance при деплое: кластер принимает только артефакты, собранные доверенным workflow из доверенного репозитория. SLSA закрывает ровно тот класс атак, что случился с SolarWinds: подмену внутри сборочного конвейера.
Пытаются цитировать спецификацию и путаются в требованиях уровней. Достаточно шкалы смыслов: есть provenance → provenance подписан платформой → сборка изолирована и ключи вне досягаемости. Кто держит эту лестницу, тот понял фреймворк.
Follow-up интервьюера: чем provenance отличается от SBOM? — SBOM — из чего состоит артефакт, provenance — кто, где и из чего его собрал. Состав и происхождение; для доверия нужны оба.
43. Подпись артефактов и коммитов — зачем и как?
Две подписи на разных концах конвейера, закрывающие разные подмены. Подпись коммитов (git commit -S — GPG, SSH-ключом или через sigstore gitsign): git позволяет поставить в поле author кого угодно — git config user.email и ты «коллега»; подпись делает авторство проверяемым, а правило «в защищённую ветку — только подписанные коммиты» отсекает коммиты от имени украденных идентичностей без кражи ключа. Подпись артефактов (cosign по digest, механика из вопроса про образы): гарантирует, что между сборкой и деплоем артефакт не подменили, а с keyless-режимом — что его собрал конкретный workflow, а не человек с ноутбука. Вместе они дают сквозную цепочку: подписанный коммит → сборка на доверенной платформе → подписанный артефакт с provenance → верификация при деплое. Разрыв в любом звене — точка подмены. Честные оговорки, которые ценят: подпись коммита подтверждает ключ, а не благонадёжность автора — украденная сессия разработчика подпишет вредонос его же ключом; поэтому подписи работают вместе с ревью и коротким временем жизни ключей, а не вместо. И организационно: подписание должно быть бесшовным (gitsign, ключи из SSO), иначе люди начнут его обходить — как любую неудобную безопасность.
Отвечают «для целостности» без конкретной атаки. Пара примеров решает: коммит от чужого имени одним git config — против подписи коммитов; перевешенный тег в registry — против подписи артефактов. Абстрактная «целостность» — это незнание, оформленное красиво.
Follow-up интервьюера: подписи коммитов включили, а release-бот не умеет подписывать — что делать? — дать боту свою идентичность с автоподписью (gitsign с OIDC-токеном бота), а не выключать требование. Исключения из криптографии имеют свойство становиться правилом.
44. Воспроизводимые сборки и pin версий — образы по digest, actions по SHA
Общий принцип: всё, что участвует в сборке и деплое, должно быть зафиксировано неизменяемой ссылкой, иначе «тот же пайплайн» завтра собирает другое. Мутабельные ссылки — теги образов (python:3.12 сегодня и через месяц — разные образы), теги GitHub Actions (uses: some-action@v3 — владелец тега может молча перевесить его на вредоносный коммит: ровно так работала атака на tj-actions/changed-files в 2025-м), плавающие версии зависимостей. Фиксация: образы — по digest (@sha256:...), actions — по полному SHA коммита с комментарием-версией, зависимости — lock-файлы с хешами, базовые образы в Dockerfile — тоже digest. Чтобы пиннинг не превратился в заморозку навечно, обновления возит бот: Renovate умеет обновлять и digest'ы, и SHA экшенов — свежесть через явные PR, а не через молчаливую мутацию тега. Воспроизводимая сборка — следующая ступень: тот же исходник даёт побитово тот же артефакт (фиксация timestamps, порядка файлов, версий тулчейна); это позволяет независимо пересобрать и сравнить — сильнейшая проверка против закладок в сборочном конвейере, но и заметная инженерная цена, поэтому честный ответ: полная воспроизводимость — для самого критичного, тотальный пиннинг мутабельных ссылок — для всех.
Пиннят версии приложения, но экшены — по тегу и базовый образ — по latest. «Кто контролирует содержимое тега v3 у стороннего экшена?» — вопрос, после которого конфиг CI хочется переписать немедленно.
Follow-up интервьюера: digest вместо тега — что стало неудобно и как жить? — читаемость и ручные обновления; лечится ботом (Renovate двигает digest'ы с changelog в PR) и комментарием с человекочитаемой версией рядом с digest.
45. Codecov и SolarWinds — что это были за атаки и какие уроки?
Два эталонных инцидента supply chain, которые надо уметь рассказать. SolarWinds (2020): атакующие сидели в сборочной инфраструктуре и внедряли закладку в процессе компиляции — исходники в репозитории оставались чистыми, а подписанные официальные релизы Orion уходили клиентам с бэкдором; заражённые обновления получили около 18 тысяч организаций, включая госорганы США. Урок: сборочный конвейер — такая же цель, как прод, и защищается так же; исходники чистые — ничего не значит, если билд-сервер скомпрометирован; отсюда изоляция сборок, provenance и SLSA L3. Codecov (2021): атакующие через утёкший из Docker-образа credential модифицировали bash uploader — скрипт, который тысячи CI-пайплайнов скачивали с сайта и исполняли через curl | bash; модификация тихо выгружала переменные окружения джоб, то есть секреты, месяцами. Уроки: curl | bash в CI — исполнение неверифицированного чужого кода с твоими секретами (фиксируй версии и проверяй хеши/подписи); секреты в env всей джобы — готовая добыча (минимизируй scope); и мораль обоих инцидентов разом — компрометация одного звена цепочки поставки масштабируется на всех потребителей сразу, поэтому цепочка поставки — не абстракция для докладов, а рабочая поверхность атаки с прецедентами на миллиарды ущерба.
Знают названия, но не механику: «SolarWinds — это когда взломали клиентов» — нет, это когда закладку вшивал сам билд-процесс вендора. Без механики невозможно назвать уроки, а вопрос ровно про них.
Follow-up интервьюера: что из уроков Codecov проверишь в нашем CI завтра? — грепнуть пайплайны на curl | bash и скачивание скриптов без пиннинга/хеша, проверить scope секретов в джобах и включить egress-контроль раннеров: эксфильтрация из Codecov шла обычным исходящим запросом.
Блок 7. Инфраструктура и облако
46. Сканирование IaC — что ловят Checkov, tfsec, Terrascan?
Класс инструментов, которые читают Terraform/CloudFormation/Kubernetes-манифесты и находят misconfiguration до того, как он стал инфраструктурой: security group с 0.0.0.0/0 на 22-й порт, публичный S3-бакет, нешифрованный диск или снапшот, база без бэкапов и с публичным адресом, IAM-политика со звёздочками, отсутствие логирования. Checkov — самый широкий по покрытию (Terraform, K8s, Dockerfile, ARM и далее), кастомные проверки на Python или YAML; tfsec — быстрый и точный по Terraform (ныне живёт под крылом Trivy как trivy config); Terrascan — OPA/Rego-политики под капотом. Ключевое преимущество сканирования IaC перед сканированием облака: находка приходит на PR, до создания ресурса, — фикс стоит одну правку в ревью, а не миграцию живой инфраструктуры; это shift-left в чистом виде. Практика внедрения та же, что у любого сканера: baseline, точечные подавления с комментарием (у Checkov — инлайн checkov:skip с обоснованием), блокировка только high/critical на новых изменениях. Плюс не забыть про сканирование плана, а не только кода: terraform plan в JSON показывает итоговые значения после подстановки переменных — часть дыр видна только там, потому что в коде стоит переменная, а опасное значение приезжает из tfvars.
Не отличают сканирование IaC-кода от сканирования облака и не знают, зачем сканировать plan. «В коде переменная encrypted = var.encrypt — сканер кода что скажет?» — ничего определённого; ответ появляется на уровне плана.
Follow-up интервьюера: IaC-сканер зелёный — облако безопасно? — нет: он видит только то, что описано кодом. Ручные ресурсы, дрифт и связки между ресурсами — слепые зоны; для них следующий вопрос.
47. CSPM — зачем, если IaC уже сканируется?
Потому что IaC-сканер проверяет намерение, а CSPM (Cloud Security Posture Management) — реальность. Между ними три зазора. Дрифт: ресурс создан кодом правильно, а потом кто-то руками открыл security group «на минутку, для дебага» — код по-прежнему чистый, реальность дырявая. Ручные ресурсы: всё, что создано в консоли мимо Terraform, для IaC-сканера не существует, а таких ресурсов в живом облаке всегда больше, чем хочется верить. Контекст и связки: опасность часто не в одном ресурсе, а в комбинации — публичный инстанс с ролью, у которой доступ к бакету с данными; это видно только на графе реального облака. CSPM (облачные native-сервисы вроде Security Hub, опенсорс типа Prowler и CloudQuery, коммерческие платформы) непрерывно инвентаризирует облако через API, сверяет с бенчмарками (CIS) и compliance-профилями, находит публичные бакеты, вечные ключи, отключённые логи, широкие роли — и главное, делает это постоянно, а не в момент PR. Зрелая связка: IaC-скан ловит до создания, CSPM — после, и расхождение между ними само по себе сигнал (дрифт — повод чинить процесс, а не только ресурс). Ответ уровня сеньора включает и реакцию: находки CSPM без владельцев и SLA — это дашборд стыда, а не безопасность.
Считают CSPM «ещё одним сканером» и не могут назвать, что именно он видит такого, чего не видит IaC-скан: дрифт, ручные ресурсы, связки. Три слова — и ответ состоялся; без них — нет.
Follow-up интервьюера: CSPM завалил команду тысячей находок — что дальше? — та же дисциплина, что со сканерами кода: приоритизация по exposure и данным, baseline, автофиксы для типового (публичный бакет — закрыть автоматически), владельцы и SLA. Иначе это шум.
48. IAM least privilege в облаке — роли вместо ключей, условия, границы
Три уровня зрелости облачного IAM. Первый — избавиться от статичных ключей: долгоживущий access key в конфиге или CI — главный источник облачных инцидентов; вместо них — роли: инстансы и поды получают временные креды через metadata/IRSA-механизмы, CI — через OIDC-федерацию, люди — через SSO с MFA и временными сессиями. Цель, которую стоит проговорить явно: ноль вечных ключей как политика, проверяемая CSPM. Второй — узкие политики: не s3:* на всё, а конкретные действия на конкретные ресурсы; писать помогает анализ фактического использования (Access Advisor и аналоги показывают, какими правами роль реально пользовалась, — остальное срезается). Плюс условия в политиках: доступ только из VPC, только с MFA, только к тегированным ресурсам — условия превращают плоское «можно» в контекстное. Третий — границы против эскалации: permission boundaries и SCP ограничивают потолок — даже админ аккаунта разработки не может выйти за организационные рамки (отключить логирование, покинуть регион, создать пользователя с ключами). Классические дыры для самопроверки: право iam:PassRole с широким ресурсом (передал привилегированную роль своему инстансу — эскалировался), iam:CreatePolicyVersion и родня — права на изменение прав и есть настоящий admin.
Говорят «выдаём минимальные права» как заклинание, но не знают ни одного механизма: чем роли лучше ключей, что дают условия, зачем boundaries. И почти никто не называет PassRole — классику тихой эскалации.
Follow-up интервьюера: как на практике сузить роль, которой два года и «всё работает»? — по телеметрии использования: собрать фактические действия за 90 дней, сгенерировать политику по ним, выкатить с алертом на deny вместо жёсткого отреза — и дожать по результатам.
49. Сегментация сети: bastion, приватные подсети, WAF — что решает каждый слой?
Принцип: наружу торчит минимум, всё остальное достижимо только через контролируемые точки. Приватные подсети — база: приложения и базы данных живут без публичных адресов, наружу ходят через NAT, входящий трафик принимает только балансировщик в публичной подсети. Один этот шаг убирает сервисы из-под интернет-сканеров, которые находят новый открытый порт за минуты. Bastion — контролируемый вход для администрирования: единственная точка SSH-доступа с MFA, аудитом и записью сессий вместо «22-й порт открыт на каждой машине»; современная замена — SSM Session Manager и аналоги, где входа по сети нет вообще, а есть брокер с IAM-аутентификацией и полным логом — bastion без bastion'а. WAF — фильтр L7 перед публичными приложениями: режет известные паттерны атак (инъекции, сканеры, боты), даёт rate limiting и — главная операционная ценность — виртуальный патчинг: правило против свежей CVE ставится за час, пока фикс едет через пайплайн. Что WAF не решает, спрашивают обязательно: логические уязвимости приложения (IDOR, сломанная авторизация), атаки, не похожие на сигнатуры, и всё, что внутри периметра, — восточно-западный трафик он не видит вовсе. WAF — эшелон, выигрывающий время, а не замена безопасному приложению.
Продают WAF как решение безопасности приложения. Вопрос «от чего WAF не спасёт?» обязателен — и ответ «от сломанной авторизации и логических багов» отделяет тех, кто читал маркетинг, от тех, кто разбирал реальные обходы.
Follow-up интервьюера: зачем bastion, если есть VPN? — это дополняющие слои: VPN — доступ в сеть, bastion/SSM — контролируемый и записанный доступ к хостам. VPN без брокера доступа означает «в сети — значит везде», а это и есть отсутствие сегментации.
50. Патч-менеджмент серверов — как обновляться и не бояться?
Страх «обновление всё сломает» лечится процессом, а не откладыванием: сервер, не патченный год, — это год известных публичных уязвимостей. Механика по нарастанию автоматизации. Автообновления безопасности: unattended-upgrades с профилем security-only — минимальный риск (security-патчи консервативны) при закрытии главного потока дыр; для парка — управляемые патч-сервисы или Ansible-прогоны по расписанию. Окна и волны: обновления катятся не на всё сразу, а волнами — сначала канареечные ноды (небольшая доля с наблюдением метрик), потом остальное; проблемный патч ловится на канарейке, а не в тотальном даунтайме. Kubernetes здесь союзник: нода — расходник, обновление — это drain, апгрейд, возврат, и приложения с корректными PodDisruptionBudget не замечают процесса; логическое завершение — иммутабельные ноды, где «патч» это замена образа ноды на свежий, а не apt-get на живой системе. Ядро и ребуты: патчи ядра требуют перезагрузки, и невыполненные ребуты — классика («пропатчено, но ядро старое, потому что аптайм жалко»); live patching существует, но это отсрочка, а не замена. И измеримость: доля хостов, патченных за SLA, и возраст самого старого непатченного — метрики, которые превращают «мы стараемся» в управляемый процесс.
«Обновляем вручную по мере возможности» — то есть никогда. Второй провал — не знают про необходимость ребута после kernel-патчей: пакет обновлён, uptime 400 дней, уязвимое ядро в памяти.
Follow-up интервьюера: вышел патч ядра под активно эксплуатируемую CVE — ждёшь окна? — нет, критичные исключения из регламента должны быть предусмотрены регламентом: экстренная волна с канарейкой в часы, а не «в третий четверг месяца».
51. Харденинг Linux-хоста — минимальный обязательный набор
SSH первым делом: аутентификация только по ключам (PasswordAuthentication no), root-логин запрещён (PermitRootLogin no) — вход под персональным пользователем плюс sudo, чтобы в логах был человек, а не «root с неизвестного IP»; fail2ban или аналог против брутфорса — хотя при отключённых паролях он больше чистит логи от шума, чем спасает. Поверхность: минимум установленных пакетов и запущенных сервисов — каждый демон это площадь атаки; периодическая сверка «что слушает порты» (ss -tlnp) с тем, что должно. Файрвол хоста с default-deny на вход даже внутри «доверенной» сети — сегментация начинается с хоста. Аудит: auditd с правилами на чувствительное — изменения в /etc, исполнение привилегированных команд, доступ к учётным файлам; логи уезжают на внешний сервер немедленно, потому что первым делом атакующий чистит локальные. Целостность и права: контроль SUID-бинарей, sysctl-харденинг (запрет ip_forward где не нужен, ограничение ptrace), автоматическая проверка соответствия через CIS-бенчмарк (OpenSCAP, Lynis) — не для галочки, а как регрессионный тест конфигурации хоста. И честная рамка: харденинг описывается кодом (Ansible-роль, образ), а не героическими руками, — иначе второй сервер уже отличается от первого.
Называют «отключить root и поставить fail2ban» и останавливаются. Про auditd с отправкой логов наружу, ревизию слушающих сервисов и харденинг как код — тишина, а это и отличает чеклист из интернета от эксплуатации.
Follow-up интервьюера: зачем логи именно наружу и немедленно? — локальный лог принадлежит тому, кто владеет хостом; после компрометации он недостоверен целиком. Форензика строится на копии, до которой атакующий не дотянулся.
52. Шифрование в транзите и at rest — TLS везде, mTLS между сервисами
Два независимых вопроса: «кто читает данные на проводе» и «кто читает данные на диске». В транзите: TLS обязателен не только на периметре — модель «снаружи HTTPS, внутри HTTP, у нас же приватная сеть» умерла вместе с представлением о непробиваемом периметре: атакующий внутри сети читает весь плоский трафик. Отсюда TLS на внутренних вызовах, к базам и очередям тоже. mTLS добавляет вторую половину: не только клиент проверяет сервер, но и сервер — клиента по сертификату, и это даёт рабочую identity сервисов — основу zero-trust-сегментации «сервис A может звать сервис B» вместо доверия по IP. Руками mTLS на сотне сервисов не живёт — ротацию и раздачу сертификатов автоматизируют service mesh (Istio/Linkerd делают mTLS прозрачно для приложения) или SPIFFE/SPIRE; для периметра и внутренних сертификатов — cert-manager с короткими сроками жизни. At rest: диски, бакеты, снапшоты и бэкапы шифруются штатными средствами облака или LUKS — это дёшево и закрывает кражу носителя и небрежность с снапшотами; ключи — в KMS с аудитом и ротацией, а не рядом с данными. Оговорка зрелости: шифрование at rest не защищает от атакующего, вошедшего через приложение, — оно про носители и бэкапы; слои отвечают каждый за свой класс угроз, и подменять один другим нельзя.
«У нас всё шифруется» без деления на транзит и rest и без ответа, где ключи. Вопрос «от чего защищает шифрование диска, если атакующий уже в приложении?» — честный ответ «ни от чего» — проверяет понимание границ каждого слоя.
Follow-up интервьюера: mTLS включили — можно снимать NetworkPolicy? — нет, слои разные: mTLS — «кто ты», политики — «кому куда можно». Identity без ограничения потоков не мешает скомпрометированному сервису со своим валидным сертификатом ходить куда угодно.
Блок 8. Процессы, уязвимости, инциденты
53. CVE и CVSS — как триажить поток уязвимостей?
CVE — идентификатор уязвимости, CVSS — оценка её серьёзности от 0 до 10 по формуле из вектора атаки, сложности, требуемых привилегий и влияния. Главная мысль ответа: голый CVSS — плохой приоритизатор. Оценка описывает худший случай уязвимости вообще, а не риск в твоей среде: critical 9.8 в библиотеке, которая не вызывается, во внутреннем сервисе за тремя периметрами — ниже по реальному приоритету, чем high 7.5 в публичном API. Триаж строится на трёх осях сверх скора. Эксплуатируемость: EPSS даёт вероятность эксплуатации в ближайший месяц по реальной телеметрии, CISA KEV — список того, что уже эксплуатируется в дикой природе; попадание в KEV — автоматический приоритет вне очереди. Exposure: доступен ли уязвимый компонент из интернета, из соседних сервисов или только локально. Достижимость: вызывается ли уязвимый код вообще — reachability-анализ в зрелых SCA режет поток в разы. Итоговая формула на пальцах: KEV/эксплойт в наличии + интернет-exposure = чинить сейчас; высокий EPSS + достижимость = в ближайший спринт; остальное — по SLA severity. Кто триажит по одному CVSS, тот тонет в критах и пропускает то, что реально ломают.
Знают CVSS, не знают EPSS и KEV — а это рабочие инструменты триажа последних лет. «У вас 200 критов, чинить все сразу?» — вопрос на приоритизацию, и ответ «да» неправильный.
Follow-up интервьюера: чем EPSS отличается от CVSS, оба же скоры? — CVSS — насколько плоха уязвимость по устройству, EPSS — вероятность, что её реально будут эксплуатировать. Серьёзность и вероятность — разные оси; риск — их произведение на твой exposure.
54. Vulnerability management как процесс — из чего он состоит?
Не «мы запускаем сканер», а замкнутый цикл. Обнаружение: непрерывное и по всем слоям — код, зависимости, образы, хосты, облако; разовые сканы дают снимок, устаревающий назавтра. Агрегация и дедупликация: одна уязвимость видна пяти сканерам в двадцати образах — без сведения в единую систему (DefectDojo и аналоги, вплоть до дисциплинированного трекера) команда получает двадцать тикетов про одно и то же. Триаж: приоритет по эксплуатируемости и exposure из прошлого вопроса, с решением по каждой позиции — фикс, митигация, риск принят (кем и до когда). Назначение: у каждой уязвимости есть владелец-команда, а не «безопасники разберутся»; маршрутизация автоматическая — по владельцу сервиса. SLA по severity: например, critical — дни, high — пара недель, medium — квартал; цифры зависят от компании, важно, что они есть, согласованы и измеряются. Верификация: закрытие подтверждается ресканом, а не словом «пофиксили». Отчётность: тренд открытых уязвимостей по возрасту и severity, соблюдение SLA, среднее время фикса — метрики процесса, а не список дыр. И петля улучшения: повторяющиеся классы находок — сигнал чинить системно: шаблон, базовый образ, обучение — а не закрывать одно и то же ежемесячно.
Описывают сканер и тикеты, пропуская SLA, владельцев и верификацию ресканом. «Кто отвечает за фикс и что будет при просрочке SLA?» — вопрос, отделяющий процесс от активности.
Follow-up интервьюера: команда стабильно не укладывается в SLA — что делать? — сначала диагноз: SLA нереален, поток не триажирован или нет капасити. Лечение соответствующее: пересмотр SLA, reachability-фильтры, выделенное время на security-долг — а не эскалация ради эскалации.
55. Признаки компрометации сервера или кластера — и первые действия
Признаки, по классам: процессы и нагрузка — незнакомые процессы, CPU в потолке без причины (майнер — самый частый гость), процессы из /tmp или /dev/shm; сеть — исходящие соединения на незнакомые адреса, DNS-запросы к странным доменам, всплеск исходящего трафика (эксфильтрация); персистентность — новые cron-задачи, systemd-юниты, ssh-ключи в authorized_keys, новые пользователи; следы заметания — очищенные логи, остановленный auditd; в кластере — поды и ServiceAccount'ы, которых никто не создавал, всплеск запросов к API в audit log, exec в контейнеры среди ночи. Первые действия — и здесь проверяют дисциплину, а не героизм. Изолировать, не выключая: вывести из балансировки, отрезать сеть (security group, NetworkPolicy, cordon ноды) — машина остаётся живой. Не перезагружать и не «чистить»: ребут уничтожает содержимое памяти — ключи, процессы, соединения атакующего, — а поспешное удаление файлов уничтожает улики и извещает атакующего. Снять форензику: дамп памяти, образ диска, копии логов — до любых изменений. Ротировать креды, до которых машина дотягивалась: токены, ключи, сертификаты — считая их утёкшими. Дальше — по процессу incident response: расследование по сохранённым уликам, поиск того же следа на соседях (атакующий редко ограничивается одной машиной), восстановление только пересозданием из чистых образов — «вычищенная» машина не считается доверенной.
Первым действием называют перезагрузку или удаление подозрительных файлов — то есть уничтожение улик. «Изолировать, сохранить, потом трогать» — порядок, который проверяется этим вопросом в лоб.
Follow-up интервьюера: бизнес требует немедленно вернуть сервис — конфликт с форензикой, как решаешь? — трафик уводится на чистые реплики/пересозданные ноды, скомпрометированная машина остаётся изолированной для разбора. Восстановление сервиса и сохранение улик — параллельные задачи, а не выбор.
56. Пентест, bug bounty, сканер — что даёт каждый?
Три инструмента с разной экономикой и разным классом находок — они складываются, а не заменяются. Сканеры: автоматика, непрерывность, копейки за проверку — ловят известное: CVE, misconfiguration, типовые паттерны. Не находят логику: сломанную авторизацию, обход бизнес-процесса, цепочки из трёх мелочей, дающие критику. Это гигиенический слой: без него люди тратят дорогое время на то, что находится грепом. Пентест: люди по договору, ограниченный срок и scope, методология и отчёт — находят как раз логику и цепочки, дают срез «что может атакующий с таким-то уровнем за две недели». Слабость симметричная: снимок на дату — через месяц после пентеста система уже другая; качество зависит от исполнителя; scope режет реализм. Регулярный пентест часто ещё и требование комплаенса. Bug bounty: непрерывность пентеста плюс разнообразие — сотни исследователей с разными подходами, оплата за результат; но это программа, а не кнопка: нужен зрелый процесс триажа репортов, быстрые фиксы и бюджет, иначе поток дублей и обиженные исследователи. Запускать bounty до того, как вычищено найденное сканерами и пентестом, — платить исследователям за то, что нашёл бы бесплатный инструмент. Последовательность зрелости: сканеры → регулярный пентест → bug bounty на вычищенное.
Отвечают «пентест лучше сканера» или наоборот — сравнивая несравнимое. Правильная рамка — какой слой находок закрывает каждый и в каком порядке внедрять; слово «логические уязвимости» в ответе обязано прозвучать.
Follow-up интервьюера: отчёт пентеста получен — что с ним делать, кроме «починить»? — разобрать классы: каждая находка — вопрос «почему её не поймали раньше и каким слоем должны были»; пентест, который не улучшил автоматику и процесс, куплен зря.
57. Как писать post-mortem по security-инциденту?
База та же, что у любого post-mortem: без обвинений, с таймлайном и action items. Специфика безопасности — в четырёх местах. Таймлайн длиннее, чем кажется: не «от алерта до фикса», а от первого проникновения до полной зачистки — и время необнаружения (dwell time) в нём самая неприятная и самая полезная метрика: сколько атакующий жил в системе, пока его не видели. Механика атаки описывается цепочкой: точка входа → закрепление → перемещение → цель; для каждого звена — вопрос «каким слоем защиты это должно было ловиться и почему не поймалось»: не поймал сканер, не было политики, алерт был, но утонул. Именно из этой таблицы, а не из общих соображений, рождаются настоящие action items — и они делятся на «закрыть эту дыру» и «закрыть класс дыр»: второе ценнее. Blameless здесь важнее, чем в обычной эксплуатации: инженер, кликнувший фишинг или закоммитивший секрет, — не первопричина, а свидетель отсутствия защитного слоя (почему фишинг дошёл, почему секрет не поймал хук); накажи его — и следующий инцидент будут скрывать. Отличие от аварийного post-mortem: круг раскрытия — детали уязвимости до фикса не публикуются широко, есть юридические и регуляторные обязательства (уведомления по 152-ФЗ или GDPR — со сроками и штрафами). Финальный тест хорошего документа: человек со стороны понимает, что случилось, почему и что теперь не даст этому повториться.
Пишут «усилим контроль и проведём обучение» как action items — это не действия, а заклинания. Каждый item — конкретен, с владельцем и сроком: «включить push protection во всех репозиториях до конца месяца, ответственный X».
Follow-up интервьюера: почему dwell time — ключевая метрика? — потому что ущерб растёт со временем доступа, а долгий dwell time означает провал детекта, независимо от того, как красиво отреагировали после обнаружения. Улучшение детекта — обычно главный вывод разбора.
58. Комплаенс на пальцах — зачем бизнесу SOC 2, PCI DSS, 152-ФЗ?
Комплаенс — это способность доказать третьей стороне, что безопасность не на словах. Зачем бизнесу: SOC 2 — пропуск на рынок B2B, особенно западный: без отчёта аудитора о контролях (безопасность, доступность, конфиденциальность) энтерпрайз-клиент не подпишет договор — это прямые деньги, а не бюрократия. PCI DSS обязателен всем, кто касается карточных данных: конкретные технические требования — сегментация среды карточных данных, шифрование, логирование, регулярные сканы и пентесты; несоответствие — штрафы и потеря права работать с картами. 152-ФЗ — российский закон о персональных данных: локализация данных граждан РФ, уведомление Роскомнадзора, требования к защите по уровням; для инженера это про то, где физически стоят базы и как оформлена обработка. Что комплаенс меняет для инженера практически: появляется слово «доказательство» — недостаточно делать ревью и логирование, нужно уметь показать аудитору артефакты (настройки, логи, тикеты); часть решений диктуется снаружи (retention логов, сегментация, ротация); ежегодные аудиты и сканы становятся частью календаря. Честная зрелая позиция, которую ждут: комплаенс — это пол, а не потолок: соответствие стандарту не равно защищённости (взломанных PCI-компливентных компаний хватает), но отсутствие соответствия — измеримый бизнес-риск. Инженерный лайфхак: автоматизировать сбор доказательств (policy as code, отчёты из CSPM) — иначе каждый аудит съедает недели ручной сборки скриншотов.
Отмахиваются «комплаенс — это бумажки». Для бизнеса это доступ к рынку и право работать с картами и персданными; инженер, который это понимает, разговаривает с бизнесом на одном языке — и это заметно на собесе.
Follow-up интервьюера: компания прошла аудит — значит защищена? — нет: аудит проверяет наличие и работу заявленных контролей на выборке, а не отсутствие дыр. Комплаенс и безопасность коррелируют, но не тождественны — и путать их опасно в обе стороны.
59. Безопасность как культура — security champions и «безопасно по умолчанию»
Масштабирование — центральная проблема: security-инженеров всегда на порядки меньше, чем разработчиков, и вручную смотреть всё они не смогут никогда. Два рабочих механизма. Security champions: в каждой команде — свой разработчик с дополнительной security-ролью: первым смотрит находки сканеров своей команды, участвует в threat modeling, приносит контекст команды в security и обратно. Важно, что это не «назначенный крайний»: роль добровольная, с выделенным временем, обучением и сообществом чемпионов — иначе программа умирает за квартал, оставшись строчкой в чьих-то OKR. Secure defaults: самый высокий ROI из всего блока — безопасный путь делается путём наименьшего сопротивления: шаблон нового сервиса уже содержит securityContext, NetworkPolicy, пайплайн со сканерами и секреты через Vault; базовые образы — из внутреннего харденед-каталога; «золотые» модули Terraform с шифрованием и приватностью по умолчанию. Разработчик получает безопасность, не принимая ни одного security-решения, — а решения против дефолта требуют явного действия, которое видно на ревью. Плюс обучение на своём материале: разборы реальных находок и инцидентов компании работают лучше абстрактных курсов. Культура измерима: доля сервисов на золотых шаблонах, время жизни находок, доля инцидентов, о которых сообщили сами команды, — последнее особенно: люди, которые не боятся принести плохую новость, и есть культура. Как и на собеседованиях, честность про проблемы ценнее парадного фасада.
Отвечают «проводить тренинги». Обучение без изменения дефолтов — самый дорогой и наименее работающий инструмент: через месяц после тренинга люди делают как удобно, и если удобное небезопасно — проиграли.
Follow-up интервьюера: как понять, что программа champions работает, а не существует? — по потоку в обе стороны: находки закрываются быстрее в командах с чемпионом, вопросы к security приходят до релиза, а не после инцидента, и чемпионы не разбегаются через полгода.
60. Как измерять эффективность security-программы?
Плохие метрики — те, что растут от активности, а не от результата: число находок сканера, число проведённых тренингов, число закрытых тикетов. Ими легко отчитываться и невозможно управлять. Рабочие метрики — про скорость, покрытие и исход. Скорость: MTTR по уязвимостям в разрезе severity (сколько живёт critical от обнаружения до фикса), время от утечки секрета до ротации, dwell time инцидентов — насколько быстро видим и реагируем. Покрытие: доля репозиториев со сканерами и push protection, доля сервисов на золотых шаблонах, доля namespace с enforce-политиками, доля образов с подписью — насколько широко работают контроли, потому что контроль на 40% инфраструктуры — это дыра на 60%. Качество потока: точность сканеров (доля подтверждённых находок), соблюдение SLA, возраст самой старой открытой критичной уязвимости — последняя цифра отрезвляет лучше любого дашборда. Исход: результаты red team и пентестов в динамике (та же команда через год проходит дальше или упирается раньше?), доля инцидентов, обнаруженных своими средствами, а не сообщённых снаружи. И дисциплина представления: метрики показывают тренд, а не снимок, и привязаны к решениям — метрика, по которой никто ничего не делает, это украшение. На собесе вопрос проверяет зрелость мышления: кандидат, который меряет безопасность числом найденных уязвимостей, будет её изображать; кандидат, который меряет временем жизни дыр и покрытием контролей, будет ей управлять.
Называют «количество уязвимостей» как главную метрику. Она растёт от улучшения сканирования и падает от его отключения — метрика, которую можно улучшить, сделав хуже, не метрика.
Follow-up интервьюера: одна метрика, если разрешена только одна? — время жизни критичной уязвимости от обнаружения до фикса: в ней сходятся детект, триаж, процесс и приоритеты. Плохая программа не удержит её низкой ни при каком отчёте.
Подготовка к собеседованию
Помогаю готовиться лично: мок-собеседования, разбор ответов, стратегия под конкретную компанию. Пишите в Telegram.
Мок-собесы и разбор ваших ответов — в менторстве и закрытом чате.