Привет, сообществу Habr!

Хочу поделиться опытом с коллегами -  как мы решили одну из наболевших проблем нашей команды разработки – отсутствие полноты данных для тестирования реализованного функционала в условиях ограниченного доступа к реальным данным компании. Если вы работаете с персональными данными, то наверняка сталкивались с такой проблемой.

Наша команда Neoflex работает на проектах заказчика. При старте работ мы всегда подписываем NDA, но все равно этого недостаточно, чтобы владелец доверил нам полный доступ к промышленным данным. Мы его прекрасно понимаем: данные -  основа благополучия компании и видеть их должен ограниченный круг лиц, отвечающий за бизнес-результат.

Чтобы удовлетворить ожидания заказчика, выполнить вверенную нам работу и достичь высоких результатов при разработке функционала, нам нужны данные для тестирования, близкие к реальным. Тут возникает сложность – на тестовом контуре либо небольшой срез не консистентных промышленных данных, на которых нельзя протестировать полноценно функционал (например, витрину по операциям определенного сегмента клиентов с глубиной месяц, квартал), либо мы начинаем генерировать синтетику, не всегда попадая в нюансы вариативности данных, тратя на это дополнительные ресурсы.

Периодически наши члены команды на ретроспективе, разбирая проблемный кейс, обсуждали свою боль – нужен тестовый контур для тестирования с достаточным количеством данных, близких к бизнесовым, обновляемый по расписанию - иначе мы можем выкатить на прод слабо оттестированный функционал. 

Но как организовать такой подход чтобы учесть интересы всех: владелец данных будет спокоен, что они не попадут в открытом виде на тест, а команда разработки получит необходимые данные, близкие к реальным?

Если проблема есть – надо найти функциональное решение

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

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

Проблема долго зрела и мы решились разработать свое решение, которое позволит нам снизить риски заказчика по доступу к персональным данным широкому кругу лиц и закрыть боли нашей команды разработки – тестирование на неактуальных данных. Наш выход  –  маскирование обнаруженных чувствительных данных при переносе с контура prod на test.

Звучит довольно просто – найти в хранилище все персональные данные клиентов ФИО, паспорта, СНИЛС, ИНН… и замаскировать при переносе с прода на тест? Первая сложность – сначала их нужно найти.

Мы хотели начать с проектной документации, описывающей таблицы хранилища, но вскоре остановились. Формально в документации указано одно, а фактически:

  • ФИО и телефоны лежат в «служебных» таблицах;

  • паспортные данные попали в комментарии;

  • e-mail хранится в нескольких форматах;

  • ИНН и СНИЛС не всегда валидны.

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

Мы постарались собрать вопросы заказчика относительно функционала маскирования данных:

  • Кто будет размечать данные (вручную/полуавтоматический + помощь заказчика)

    • Если вручную, то нельзя делать это руками подрядчика - он данные видеть не должен

  • Какие поля будут признаны чувствительными?

    • Вдруг разметят неправильно, можно ли вносить правки?

  • Какие варианты маскирования данных возможны?

  • Можно ли воспроизвести процесс неоднократно авт��матически?

Рассмотрев опасения заказчика, мы пошли в сторону решения, при котором система сама будет производить поиск персональных данных автоматически, исходя из преднастроенных правил идентификации – т.е. никто из команды разработки данные не видит, только структуру хранения.

Достаточно будет указать варианты наименования полей (не обязательно указывать точно, достаточно маски), в которых могут храниться данные клиентов – это может сделать сам заказчик. Дальше система проанализирует все таблицы хранилища, проверит сами данные, в этих полях и подскажет пользователю где с высокой долей вероятности лежат чувствительные.

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

  1. Можно настраивать справочники для первичного поиска полей по наименованию;

  2. Редактировать результаты аудита вручную – снимать или выставлять признак маскирования;

  3. Выбирать типы маскирования;

  4. Сохранять ранее примененные настройки для маскирования таблиц – профиль маскирования (это позволит выполнять маскирование по уже согласованному набору правил в будущем).

Ручное маскирование не масштабируется

  • Данные маскируются неконсистентно;

  • При изменении структуры хранения данных, ранее созданные скрипты теряют актуальность;

  • Невозможно повторить процесс на периодической основе;

  • Отсутствие единых правил приводит к тому что одни и те же по структуре персональных данные могут быть замаски��ованы по-разному либо не замаскированы вовсе.

К каким последствиям это приводит:

  • Тесты больше не воспроизводят реальные сценарии;

  • Аналитика даёт некорректные результаты;

  • Идентификаторы теряют связи;

  • В итоговый результат просачиваются незамаскированные данные.

Ручное маскирование действительно быстрее в случае одноразовой задачи, но нашу проблему с актуальным тестовым стендом, пополняемым новыми данными оно не решает. Т.е. большие хранилища предполагают ежедневное обновление самих данных при сравнительно редком обновлении структуры данных. Это делает логичным сохранение правил маскирования для каждого объекта (таблицы) в профиле для последующего их многократного применения.

Какие функции являются базовыми для нашего решения?

  • Наш инструмент автоматически находит чувствительные данные на основании настраиваемых критериев:

    • Персональные данные;

    • Идентификаторы;

  • Понимает контекст, а не только формат;

  • Маскирует данные воспроизводимо и управляемо;

    • Замена на реалистичные значения;

    • Маскирование по шаблону

    • Хэширование в комбинации с солью

    • Перестановка

    • Частичное сокрытие данных.

  • Не ломает связи и бизнес-логику;

    • Ключи можно замаскировать с помощью hash;

  • Может быть встроен в существующие процессы;

  • Отслеживает изменение структуры данных источника.

    • Если на источнике изменилась структура, то новые поля будут маскироваться в автоматическом режиме до тех пор, пока администратор не отметит поле немаскируемым. Это снижает риск утечки чувствительных данных.

Ключевые особенности.

  • Построен на Open Source технологиях

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

  • Разные типы маскирования с возможностью добавления своих типов;

  • Анализ структуры базы данных происходит в автоматическом режиме;

  • Предопределенные критерии поиска чувствительных данных, подходящих под 152 ФЗ;

  • Простота интеграции в существующие процессы

    • В ETL / ELT-пайплайны;

    • В CI/CD;

  • Работа с СУБД PostgreSQL, GreenPlum, Hive;

  • Сохранение настроек для повторного использования на других средах;

  • Возможность посылать уведомления администратору, при изменении данных на источнике.

Примеры маскирования

Маскирование чисел                                     

Продуктовая
 база

Маскированная копия базы

1259890

8988356

2345523

23*****

345566978

Const

Замена числа производится с сохранением разрядности. Маскирование ИНН, СНИЛС происходит с сохранением контрольных сумм и ОКАТО.

Маскирование текста

Продуктовая
 база

Маскированная копия базы

Иванов

Жуков

Анна

А***

Москва

Астрахань

Замена имен, отчеств, городов, фамилий происходит на справочные значения, что обеспечивает реалистичность данных.

Маскирование дат                                   

Продуктовая
 база

Маскированная копия базы

24.06.2024

12.08.2022

24.06.2024

01.06.2024

24.01.2026 10:51

25.08.2024 13:30

Замена дат осуществляется либо на первый день месяца, либо на значение в диапазоне до 2000 дней от текущей с сохранением формата.

Удалось ли попробовать запуск на реальных данных?

Да. Для нас это было огромным шагом вперед.

Наш заказчик доверил нам проведение эксперимента на его данных. Функционал отработал и показал следующие результаты:

Мы идентифицировали данные, которые хранились в явном виде, например, в поле address находились точно адреса. Сложности возникли с полями, которые назывались неоднозначно – их заказчик размечал вручную (тут нам очень помог интерфейс, т.к. заказчик мог делать это самостоятельно). Донастройка шла постепенно, это потребовало времени.

Приходилось переделывать в процессе справочники, т.к. типы данных разнились, например, ИНН где-то хранится как строка, а где-то число. 

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

Несмотря на наши опасения, что результат появился не одномоментно – заказчику понравился механизм маскирования, т.к. он сам принимал участие в процессе и видел, как меняется результат.

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

Что по скорости маскирования?

Приведу пример маскирования типовой таблицы в 8 млн записей, 20 полей, ~ 1ГБ данных (все — ПДн).

Результат: Полное маскирование заняло ~13 минут.

Инфраструктура: PostgreSQL, 35 ядер CPU, 120 ГБ RAM, SSD.

Что в планах?

Мы не стоим на месте. Добавили в бэклог следующие идеи:

  • Маскирование составных ключей;

  • Нахождение чувствительных данных в текстовой строке;

  • Автоматизация маскирования при копировании данных на тестовый контур – по расписанию;

  • Применение ML для более точного поиска чувствительных данных;

  • Расширение списка возможных источников данных.

Мы будем рады обсудить опыт, кейсы и подводные камни деперсонализации данных – и обсудить с какими решениями вы сталкивались.

P.S. Если тема интересна, вызовет живое обсуждение, можем в следующей статье рассказать, как переносим данные с прода в несколько зон для тестирования: для бизнес-аналитиков заказчика (1:1 с прода) и для остальных пользователей в том числе и для подрядчиков (с замаскированными чувствительными данными). Пишите вопросы, будем рады обсудить.