Привет! С вами снова Александр Симоненко, операционный директор Xilant. В первой статье трилогии о бизнес-требованиях мы разобрали, как неточные формулировки в требованиях создают уязвимости, а во второй — методики безопасных требований: INVEST, SMART, What-If и misuse-cases. 

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

Почему методики не работают сами по себе


Даже самая правильная методика умирает в тот момент, когда она существует в вакууме, отдельно от реального процесса разработки. SMART, INVEST, What-if, misuse-cases отлично работают на бумаге, но если вокруг них нет живого контура  требований, ревью, CI/CD, приемки они превращаются в красивую документацию.

Частая ситуация: команда честно заполняет шаблоны, проводит воркшопы, делает misuse-сессии, но результаты не попадают в тикеты, не отражаются в acceptance и никак не проверяются в CI. Формально «методика есть», фактически — безопасность по-прежнему держится на личной ответственности пары людей. В таком режиме любая нагрузка, дедлайн или кадровая ротация мгновенно обнуляет все усилия.

Методика начинает реально работать только тогда, когда она встроена в цепочку: «требование → acceptance → код → тесты → CI → приемка». Всё, что не доходит до этой цепочки, в прод не попадает.

Но именно эта цепочка чаще всего и рвется — не внутри шагов, а «в зазорах» между ними:

Между обсуждением и фиксацией. На встрече все правильно обсудили, придумали классные mitigations и негативные сценарии, а в user story это не попало. В тикете остается только «как партнер, я хочу…» без безопасности.

Между требованиями и разработкой. В Confluence красивый SMART, в Jira - короткий заголовок. Разработчик видит только тикет, а не исходный анализ, и реализует «как понял», а не «как задумывалось».

Между код-ревью и security-ревью. Code review смотрит на стиль, архитектуру и производительность, но не на угрозы. AppSec-ревью либо отсутствует, либо делается эпизодически, по настроению.

Между ревью и CI/CD. В ревью нашли, что нужен rate-limit и schema-validation, все согласовали, но шаг в CI, который это проверяет, так и не добавили. В результате через пару релизов кто-то случайно откатывает конфиг, и защита тихо исчезает.

Между CI и продом. В CI все зеленое, потому что тесты гоняются против одной конфигурации. В проде — другие настройки, другие секреты, другое окружение. Никакого финального security gate на выкатку нет, и уязвимость уезжает к пользователям.

По сути, провалы всегда один и тот же: то, что придумали в голове и обсудили в Zoom, не превращается в обязательный, проверяемый шаг процесса.

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

Security Acceptance Criteria: фича считается не только рабочей, но и безопасной

Security Acceptance Criteria — это набор условий, при выполнении которых можно честно сказать: «фича реализована не только функционально, но и безопасно». Это такой же acceptance, как «кнопка нажимается и данные сохраняются», только про шифрование, доступ, логирование и тесты.

Для историй с PII или внешними интеграциями этот блок обязателен: именно такие сценарии чаще всего становятся источником утечек и инцидентов. Без него мы заранее не договариваемся, какие данные защищаем, кто имеет к ним доступ, как фиксируем действия и какими тестами проверяем выполнение. Попытки «догонять» безопасность на этапе код-ревью почти всегда заканчиваются провалом.

Если в user story нет security-acceptance, она автоматически воспринимается как чисто функциональная. Команда делает «чтобы работало», а всё, что связано с безопасностью, остаётся в голове у AppSec, в комментариях к документу, в устной договорённости. На практике: задача закрыта, тесты зелёные, но шифрование, rate-limit и негативные сценарии не проверены. На проде случается инцидент, и все удивлённо открывают исходные требования: там никакого security не было.

Структура Security Acceptance

Рассмотрим на примере, как должен выглядеть хорошо структурированный acceptance:

Scope/Объем задач: перечислить данные (name, email, phone) и покрываемые эндпоинты (/import, /user, /admin)

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

Confidential/Конфиденциальность: шифрование при хранении и в транзите; ключи в KMS; ротация ключей каждые 90 дней

Это тот слой, который спасает даже тогда, когда всё остальное ��ошло не по плану. Если здесь сэкономить, любой доступ к базе превращается в утечку. Обязательно указывать конкретные алгоритмы (AES-256-GCM), где хранятся ключи и как часто они ротируются.

Access/Доступ: аутентификация по стандарту (OAuth2/OIDC); доступ по ролям (RBAC); MFA для админ-функций; least-privilege

Практика показывает, что большинство реальных инцидентов — как раз из-за неправильного доступа, а не отсутствия шифрования. Здесь важно не просто написать «OAuth2», а указать scope токенов, какие роли имеют доступ, где требуется MFA.

Logging/Логирование: фиксировать actor / action / resource / timestamp / reason; отправлять в SIEM; хранить 365 дн.; alert при аномалиях (напр. >10 неудачных входов/мин с одного IP)

Это не только про расследование инцидентов, но и про раннее обнаружение атаки. Если ничего не логируется, вы просто не узнаете, что что-то пошло не так. Важно указать конкретные события, которые логируются, куда отправляются логи, сколько хранятся и какие условия вызывают алерты.

Test/Тесты: unit + integration; negative tests; fuzz для парсеров; все acceptance-проверки в CI перед релизом.

Производительность и соответствие: допустимое влияние на задержку (напр., медиана +50 ms); указать применимые регуляции (GDPR / PCI / ГОСТ).

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

Разделение ответственности

Без явного деления ответственности acceptance легко превращается в набор пожеланий без конкретных исполнителей. В идеале зоны распределяются так:

BA / системный аналитик описывает Scope: какие данные, какие эндпоинты, какие акторы.

AppSec формулирует требования к конфиденциальности, доступу, логированию, тестам, помогает с what-if и misuse.

Dev реализует проверку прав, валидацию, интеграцию с крипто и логированием, отвечает за корректный код.

DevOps обеспечивает шифрование at-rest, KMS, ротацию ключей, настройки TLS, интеграцию с SIEM.

QA пишет и выполняет unit, integration, negative, fuzz-тесты, проверяет, что acceptance реально покрыт тестами.

PO / PM следит, чтобы всё это было в приоритете и не «оптимизировалось» до состояния нуля при дедлайнах.

Как не превратить acceptance в формальность

Типичные ошибки: слишком об��ие формулировки без метрик («шифровать всё», «логировать важные действия»), копипаст одного и того же текста во все тикеты, отсутствие явных владельцев, acceptance никак не связан с тестами и CI.

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

Threat Modelling: быстрый анализ угроз без килограмма диаграмм

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

Мы берём будущую фичу, смотрим, какие есть акторы, потоки данных, хранилища, где границы доверия, и задаем простой вопрос: «что здесь может пойти не так и кто этим воспользуется?». Такой формат можно делать за 15–30 минут на epic и регулярно повторять. Это не разовое «большое исследование», а практический навык команды.

Процесс выглядит так: рисуем DFD level-1 — очень простую диаграмму потоков данных. Кто отправляет запросы (пользователь, партнер, бэкенд), через какие интерфейсы (API, UI, очереди), какие компоненты обрабатывают, где данные хранятся. Обозначаем границы доверия: где внешний мир, где внутренняя сеть, где особо критичные зоны.

DFD level-1 нужен не ради красоты. Он даёт команде одинаковую картинку в голове, позволяет не тратить время на сложную архитектуру и помогает быстро увидеть очевидные дырки: внешний запрос сразу в базу, нет проверки подписи, нет аутентификации между сервисами.

Дальше применяем STRIDE — чек-лист типов угроз. Берем элемент из DFD, например endpoint /import/contacts, и проверяем его по шести категориям:

Spoofing (подмена личности) — может ли кто-то выдать себя за партнёра? Есть ли OAuth2, как валидируется client_id, где хранятся секреты, можно ли подделать токен.

Tampering (изменение данных) — можно ли подменить CSV по пути? Используется ли TLS, есть ли подпись файла, проверяется ли hash.

Repudiation (отказ от совершенных действий) — можно ли отрицать, что действие совершил конкретный пользователь? Логируются ли все операции с указанием actor, timestamp и action, защищены ли логи от изменения.

Information Disclosure (утечка информации) — может ли ответ API содержать лишние данные? Маскируются ли чувствительные поля, фильтруются ли данные по правам доступа, нет ли утечки через error messages.

Denial of Service (отказ в обслуживании) — что если злоумышленник шлёт 1000 файлов по 1 ГБ? Есть ли rate-limit, size limit, используется ли очередь для обработки.

Elevation of Privilege (повышение привилегий) — можно ли через этот endpoint получить доступ к чужим данным? Настроен ли RBAC, правильно ли работает scope токена, изолированы ли данные разных пользователей.

Для каждой найденной угрозы сразу формулируем: что мы делаем, чтобы этого не произошло. Получается короткий, но конкретный список — обычно 3–5 ключевых точек, которые покрывают 80% реального риска.

Главное — не оставлять угрозы в воздухе. Для каждой угрозы нужно создавать конкретные задачи: технические mitigations (включить шифрование at-rest, добавить подпись/валидацию входящих данных, ограничить размер запросов, добавить rate-limit, усилить аутентификацию), изменения в требованиях (обновить user stories и acceptance, добавить негативные сценарии и misuse-cases), изменения в тестах и CI (добавить negative и fuzz-тесты, настроить проверки схем и конфигураций).

Если после threat modelling не появилось ни одной задачи в backlog — это был не threat modelling, а разговор на тему «как всё страшно».

Главное — после выявления угроз не оставлять их в воздухе. Для каждой угрозы нужно созда��ать конкретные задачи:

  • Технические mitigations: включить шифрование at-rest, добавить подпись и валидацию входящих данных, ограничить размер запросов, настроить rate-limit, усилить аутентификацию.

  • Изменения в требованиях: обновить user stories и security acceptance, добавить негативные сценарии и misuse-cases.

  • Изменения в тестах и CI: добавить negative и fuzz-тесты, настроить проверки схем и конфигураций.

Если после threat modelling не появилось ни одной задачи в бэклоге, значит, это был не threat modelling, а просто разговор «как все страшно».

Теперь посмотрим, как конкретно внедрить методики в процесс, чтобы обсуждения и анализ рисков превращались в реально реализуемые user stories с проверяемыми security-требованиями.

Walkthrough: 5 шагов от плохого требования к готовой user story

Наша цель проста: превратить обсуждения, чек-листы и What-if сценарии в готовую user story с Security Acceptance и назначенными владельцами.

Лучше всего это делать в таком порядке:

  1. Сначала понять, о чём вообще задача (scope).
    Пока не ясно, какие данные, кто актор и куда всё записывается, говорить о безопасности бессмысленно. Это фундамент.

  2. Затем проверить, не забыли ли мы базовые элементы (чек-лист).
    Это быстрый скан: есть ли шифрование, доступ, логирование, тесты. Чек-лист не даёт пропустить очевидное.

  3. Потом чуть глубже копнуть через What-if.
    Это помогает увидеть не только «чего нет», но и «во что это выльется в реальности» - атаки на парсер, обход авторизации, утечки.

  4. После этого сформировать новую, нормальную user story с acceptance.
    Здесь всё знание упаковывается в артефакт, которым уже можно пользоваться в Jira и CI.

  5. И в конце не забыть завести отдельные задачи на mitigations.
    Иначе все договоренности так и останутся в описании.

Разберем walkthrough на часто встречающемся кейсе «импорт контактов партнера».

Исходная (плохая) user story. «Как партнёр, я хочу загружать CSV с контактами.»

Шаг 1 — Прочитать и понять scope (1 мин)

Вопросы: какие поля в CSV? кто загружает (партнёр/админ)? куда сохраняются данные? это PII?

Результат: Scope = name, email, phone; endpoints = POST /import/contacts; PII = да.и

Именно здесь часто вскрывается первая серия проблем: внезапно оказывается, что никто до конца не понимает, какие поля есть в CSV, это точно PII или «просто контакты», куда именно все сохраняется.

Шаг 2 — Применить чек-лист (2 мин)

Чек-лист: есть ли Scope, Confidentiality, Auth, Logging, Tests, Performance, Compliance?

  • Scope — есть (определили).

  • Confidentiality — нет (нужно добавить шифрование для PII).

  • Auth — не указано (надо OAuth2 + roles).

  • Logging — не указано.

  • Tests — нет.

Шаг 3 — Прогнать 3 What-if (2–3 мин)

Первый: что если партнёр загрузит специально сформированный CSV? → риск: parser exploit → mitigation: schema validation + sandbox.

Второй: что если файл пройдёт без авторизации? → риск: массовый слив → mitigation: OAuth2 и role checks + rate-limit.

Третий: что если PII сохраняется в открытом виде? → риск: утечка → mitigation: at-rest encryption + KMS, key rotation.


Шаг 4 — Сформировать исправленное требование + acceptance (2 мин)

Хорошая (готовая для тикета) user story (copy-paste):

Title: Partner contacts import — secure flow 

Description: Система должна позволять партнёрам загружать CSV с контактами (поля: name, email, phone) через защищённый API POST /import/contacts. 

Acceptance / Security checks: Доступ к endpoint — только по OAuth2; токены scope = partner_import; rate-limit = 100 requests/min.

Файл проходит schema-validation и size limit 10 MB; парсинг выполняется в изолированном sandbox.

PII поля сохраняются зашифрованными at-rest (AES-256-GCM); ключи в KMS; ротация ключей каждые 90 дней.

Logging: запись события загрузки (actor, file_id, record_count, timestamp); отправка логов в SIEM; retention 365 d.

Tests: unit tests for parser, integration test for end-to-end import, fuzz tests for parser; CI-job запускает проверку schema и симуляцию ротации ключей.

Owners: Dev — реализация парсера; AppSec — ревью mitigations; QA — подготовка negative tests; DevOps — KMS key management. Estimate: 5 story-points (примерно 1 sprint).

Шаг 5 — Создать задачи на mitigations и назначить (1 мин)

Создать таск: «Добавить schema validation + sandbox для import parser» (owner = Dev, acceptance = тесты, due = sprint X).

Создать таск: «Включить encryption at-rest for PII + CI key rotation test» (owner = DevOps + AppSec).

Рекомендации для максимально хорошего результата:

  • Делать walkthrough командой: BA + Dev + QA + AppSec. В одиночку всегда что-то упустишь.

  • Ставить жесткий лимит по времени: 8–12 минут на историю, чтобы не превратить это в бесконечное обсуждение.

  • Фиксировать результат в готовой user story и acceptance, а не «просто обсудили».

  • Каждый негативный сценарий должен порождать либо конкретное acceptance-условие, либо отдельную задачу на mitigation.

  • Приучить команду, что без такого walkthrough истории с PII и интеграциями просто не попадают в разработку.

Roadmap: встраиваем безопасность в процесс за 90 дней

Следующий шаг — смотреть на поток разработки в целом. Чтобы процесс работал стабильно, а не зависел от усилий отдельных людей, я советую следующий 90-дневный roadmap

Неделя 1–2: Security Acceptance Template + обязательные поля

Сначала нужно заставить безопасность появиться в требованиях как стандартный элемент, а не как исключение. Добавляем Security Acceptance Template в шаблоны задач и делаем его обязательной частью требования. Любая серьезная user story не попадает в работу, пока блок про безопасность не заполнен.

Главное здесь — не создать формальность. Шаблон должен бы��ь коротким и конкретным, а не «мини-ISO-стандартом». Поля делаем обязательными для заполнения — иначе их просто будут пропускать. В шаблоне не должно быть пунктов, которые команда заведомо не проверяет — иначе все превратится в галочки. Назначаем одного владельца (обычно AppSec или BA Lead), который следит за качеством заполнения.

Чтобы шаблон реально работал: привязываем поля acceptance к конкретным действиям — тестам, конфигам, настройкам CI. Включаем простую проверку: тикет нельзя закрыть, пока acceptance не заполнен. Раз в спринт делаем короткий разбор-полетов — смотрим 2–3 тикета, как реально выполняются acceptance. Периодически чистим шаблон: если пункт ни разу не применяли или не проверяли — либо убираем, либо делаем осмысленным.

Неделя 3–4: тренинг BA/PO — чек-лист + what-if

Теперь учим тех, кто пишет требования, видеть риски еще на уровне формулировок. Проводим 2-часовой практический воркшоп для BA/PO/Dev/QA: как использовать чек-лист и запускаем what-if сессию. Результат: user stories сразу рождаются более качественными, а не «сырой текст, который потом поправит AppSec».

Лучше всего работают воркшопы, построенные на реальных кейсах команды, а не абстрактных примерах. Берем 2–3 актуальные user stories и прямо на сессии прогоняем по чек-листу и what-if. Делаем это вслух, с комментариями — чтобы BA/PO услышали мышление AppSec и Dev. Фиксируем лучшие формулировки в живой библиотеке примеров. Ограничиваем разбор каждого кейса 10–15 минутами, чтобы команда фокусировалась на сути.

Типичные сложности с misuse-сессиями: люди боятся «думать как злоумышленник» и уходят в фантастику или, наоборот, ничего не предлагают. Команда пытается покрыть все возможные атаки, и сессия затягивается на часы. Всё обсудили, но ничего не попало в backlog.

Подробнее misuse-сессии и what-if мы разбирали во второй статье цикла о требованиях.

Месяц 2 — lightweight threat modelling для текущих эпиков

Выводим понимание угроз на уровень эпиков и архитектуры.

Для 3 текущих эпиков проводим lightweight threat modelling (15–30 мин каждый) и настраиваем pre-merge CI job, который проверяет наличие security-fields и базовые правила.

Threat modelling здесь не про тяжелые сессии — он должен быть легким, повторяемым и встроенным в рутину. Если же после сессии не изменился ни backlog, ни архитектура, ни CI — это был разговор «для галочки».

Когда threat modelling начинает работать, важно параллельно настроить CI-проверки, которые будут автоматически ловить очевидные проблемы. Здесь тоже есть свои правила.

Чтобы CI-проверки реально помогали, а не мешали:

  • Начинайте с простого: schema-validation, size limit, базовый линтинг конфигов.

  • Делайте проверки быстрыми, чтобы они не тормозили pipeline.

  • Разделяйте блокирующие и предупреждающие проверки: не всё должно падать билд.

  • Давайте разработчикам понятные сообщения об ошибках и инструкции, как исправить.

  • Следите за % ложных срабатываний - если их много, проверки будут игнорировать или отключать.

Месяц 3 — автоматизация (CI jobs, basic regex/NLP), метрики и dashboard

Убираем избыточный ручной контроль и делаем безопасность частью инженерной рутины. Разворачиваем базовый дашборд с метриками: процент требований с заполненным security-acceptance, lead-time на исправление security-issues, количество misuse cases per epic. Добавляем первые simple CI-tests (schema check job, simple fuzz job).

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

Самое полезное: автоматическое замечание «ты забыл acceptance» на этапе создания тикета, базовые проверки схем и конфигураций в CI, снятие метрик — сколько историй прошли security-check, сколько упали, сколько уязвимостей поймал pipeline до прода.

Какие метрики отслеживать?

  • % user stories с заполненным security acceptance

  • % историй, прошедших все security-проверки в CI

  • число найденных и закрытых mitigations за спринт

  • время от обнаружения угрозы до реализации mitigation

  • количество инцидентов/находок на проде, связанных с требованиями (или их отсутствием)

Эти цифры хорошо показывают, движемся ли мы от «реактивной» к «проактивной» безопасности.

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

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

Как этого избежать? Главное — двигаться итеративно: сначала acceptance, потом чек-листы, потом threat modelling, потом автоматизация. Начинать стоит с самых болезненных зон: PII, деньги, интеграции. Важно заранее договариваться о приоритетах и SLA на security-задачи, а на каждом этапе проводить ретроспективу и упрощать то, что не работает.

И еще несколько «золотых правил»:

  • Если в user story есть PII или интеграция, без security acceptance она не существует.

  • Если mitigation не попал в backlog - он не будет сделан.

  • Если проверка не встроена в CI - её будут забывать.

  • Если нет владельца - нет ответственности.

  • Если процесс нельзя пройти за 10–15 минут - он не будет выполняться регулярно.

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


Мы прошли полный путь: от понимания, почему методики умирают без процесса, до конкретного 90-дневного roadmap внедрения. 

Главное — помнить, что безопасность требований работает только тогда, когда она встроена в поток разработки. Шаблоны, чек-листы и воркшопы — это инструменты, но реальная ценность появляется, когда они становятся частью ежедневной работы команды.

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

Спасибо, что дочитали трилогию до конца. Надеюсь, что вам было интересно, а самое главное полезно — подписывайтесь на мой канал «Крупицы знаний» и на канал Xilant. Будем на связи! 

Комментарии (0)