Анонимизация данных на лету на основе шаблонов

Анонимизация данных на лету на основе шаблонов

Как работать с персональными данными в тестовых средах?

В продакшене часто требуется хранить и использовать чувствительные данные, включая персональные данные (ПД). Разработчикам в работе на тестовых окружениях иногда бывают нужны данные, максимально приближенные к реальным, уже имеющимся в продукте. Несмотря на то, что в хранении пользовательских данных всегда применяются лучшие практики, такие регламенты и законы как ФЗ «О защите персональных данных», HIPAA, HITECH, CPRA или GDPR требуют, чтобы любые персональные данные хранились и использовались только там, где это необходимо и были защищены или анонимизированы при передаче.

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

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

Именно на таком подходе и основан Datanymizer.

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

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

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

Datanymizer: ваш новый помощник, сохраняющий конфиденциальность данных

Datanymizer делает всё вышеперечисленное. Вы определяете конфигурацию, которая указывает, что делать (и не делать). Затем он выгружает данные непосредственно из вашей базы данных, применяя заданные правила. Ещё в него интегрирован движок шаблонов Tera, чтобы можно было синтезировать произвольный формат значений.

На выходе у вас получается анонимизированный SQL-дамп, записанный либо в файл, либо непосредственно в стандартный вывод, готовый к импорту с помощью родных инструментов базы данных.

Начало работы

Есть несколько способов установить pg_datanymizer. Выберите подходящий для вас.

Предварительно скомпилированный бинарный файл:

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

Теперь вы можете вызвать Datanymizer для создания изменённого дампа ваших данных:

Эти команды создают новый дамп-файл /tmp/dump.sql с нативным SQL файлом для базы PostgreSQL. Мы можете импортировать фейковые данные из этого дампа в новую базу данных с помощью команды:

Фильтры таблиц

Вы можете определить список таблиц, которые никогда не будут включаться в дамп. Например, для дампинга только public.markets и public.users data:

А для игнорирования этих таблиц при создании дампа из остальных:

Также вы можете управлять фильтрами данных и фильтрами схем независимо.

Глобальные переменные

Вы можете определить глобальные переменные доступные из любого шаблона правил:

Встроенные правила

Datanymizer имеет встроенную поддержку («правила») для определенных типов значений, а также pipeline, позволяющий генерировать значения, применяя цепочки существующих фильтров для одного поля. Другие фильтры также включают параметры email, ip, words, first_name, last_name, city, phone, capitalize, template, digit, random_number, password, datetime и другие.

Ограничения уникальности

Уникальность поддерживается правилами email, ip, phone, random_number.

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

Вы можете менять количество попыток параметром try_count. Это опциональное поле, количество по умолчанию зависит от правила.

Планы на будущее

Вот какие функции мы хотим добавить в следующих обновлениях:

Pre-filtering: например, если необходимо выдавливать не всех пользователей, а тех, которые соответствуют определенным критериям (например, 100 пользователей, в возрасте 27 лет и старше, по имени Александр), с поддержкой произвольных SQL-запросов для фильтрации. Генерация данных: если вам нужно не анонимизировать существующие данные, а генерировать синтетические, основанные на определенных правилах. Поддержка других RDBMS: сейчас Datanymizer поддерживает только базы PostgreSQL, но в будущем добавится mySQL и MariaDB. Присоединяйтесь к разработке Datanymizer и предлагайте свои идеи!

Разные технологии для разных уровней (сборка через gulp)

Допустим, в моем проекте есть 2 уровня переопределения: "lib" и "project". На обоих уровнях присутствуют технологии "js" и "helper.js". Мне нужно, чтобы в итоговую сборку попали файлы "js" и "helper.js" из "project", и только "helper.js" из "lib". Т.е. что-то вроде этого:

Можно ли такое реализовать в gulp? В документации ничего такого не нашел, даже в методологии такие кейсы не описываются. Есть, конечно, gulp-merge и другие способы объединить потоки в gulp, но они будут замедлять сборку, т.к. придется заново вызывать gulp-bem-src, он будет заново разрешать зависимости т.д..

Когда использовать микс, а когда модификатор?

Здравствуйте. Использую бэм уже продолжительное время, но до сих пор иногда оказываюсь просто в растерянности в некоторых ситуациях Есть 2 кейса:

1. Первый кейс. У нас есть блок .contacts, который используется в header, footer и на странице контакты

Во всех 3-х случаях его элементы выглядят и позиционируются немного по разному. Для позиционирования я делаю микс

Но встает вопрос, как стилизовать элементы: Давать миксы header__item и header__link не вариант, т.к. в хэдере могут уже существовать эти классы вне контекста .contacts

1) Можно создать еще один пустой микс класс

Раньше я поступал именно так. Но мне все больше не нравится такой подход. Во-первых сам класс выглядит так будто пытается выдать себя за два. Во-вторых мы создаем новый блок просто ради того, чтобы задать косметические изменения, что как мне кажется не верно.

2) Можно делать кучу модификаторов для каждого элемента в отдельности, но тогда страшно представить сколько в проекте будет модификаторов, большинство из которых будет использоваться только 1 раз.

3) Можно сделать модификатор для блока и стилизовать каскадом

Это вроде как противоречит идеям бэм, но мне кажется наиболее удачным решением.

2. Второй кейс. У нас есть базовый блок карточки

Допустим она используется в каталоге. Но так же на странице с портфолио, но выглядит немного иначе. Создавать пустой микс класс .portfolio-card мне кажется плохой практикой, т.к. мы привязываемся к контексту. А что если эта модифицированная карточка будет еще на какой-то странице? Тогда само слово portfolio уже будет ни к селу ни к городу. Микс portfolio__img , portfolio__inner и т.д. тоже не жизнеспособны, т.к. нам нужно менять элементы именно в контексте карточки.

Я пришел к тому, что лучше всего будет давать карточкам абстрактные модификаторы

И стилизовать каскадом. Это дает нам полную модульность и свободу. Мы можем использовать модифицированные карточки где угодно в проекте. Более того, можно комбинировать модифицированные карточки с модификаторами элементов как угодно, например:

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

Был бы очень рад услышать аргументированную критику и ваши мысли на этот счет.

📎📎📎📎📎📎📎📎📎📎