I.3. pg_anon#

I.3. pg_anon

I.3. pg_anon #

pg_anon — инструмент анонимизации для Tantor BE

I.3.1. Обзор #

Версия: 1.9.1

Скачать с nexus-public

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

I.3.2. Требования #

  • Python: 3.11+

  • Клиентские утилиты Tantor BE (должны соответствовать основной версии сервера):

    • pg_dump – используется для экспорта схемы базы данных

    • pg_restore – используется для восстановления схемы базы данных в целевую базу данных

Подробности смотрите в разделе: Установка и настройка

I.3.3. Терминология #

Термин Описание
Персональные (чувствительные) данные Данные, которые не должны передаваться третьим лицам. Включают личную или конфиденциальную бизнес-информацию.
Исходная база данных Оригинальная база данных, содержащая конфиденциальные данные.
Целевая база данных Пустая база данных, в которую будут восстановлены анонимизированные данные.
Мета-словарь Файл Python, описывающий правила обнаружения конфиденциальных данных. Создаётся вручную и используется в качестве основы для генерации словаря конфиденциальных данных во время сканирования. Подробнее
Подготовленный словарь чувствительных данных Файл Python, который определяет, какие таблицы и поля содержат чувствительные данные и как их анонимизировать. Создаётся автоматически или вручную. Подробнее
Подготовленный словарь нечувствительных данных Файл Python, содержащий список схем, таблиц и полей без конфиденциальных данных. Используется для ускорения повторных сканирований. Подробнее
Словарь таблиц Файл Python, содержащий список таблиц. Используется для включения или исключения таблиц при операциях дампа и восстановления. Подробнее
Создание словаря (сканирование) Процесс сканирования исходной базы данных для обнаружения конфиденциальных полей и создания файлов словаря. Подробнее
Дамп Экспорт данных из исходной базы данных в файлы с использованием словаря. На этом этапе происходит анонимизация. Подробнее
Восстановление Импорт анонимизированных данных из файлов в целевую базу данных. Подробнее
Анонимизация (маскирование) Полный процесс клонирования и очистки данных (dump → restore), при котором чувствительные значения заменяются случайными или хешированными.
Функция анонимизации Функция Tantor BE (встроенная или из схемы anon_funcs), которая заменяет конфиденциальные значения случайными или хешированными данными. Новые функции могут быть добавлены для расширения логики анонимизации.

I.3.4. Быстрый старт #

I.3.4.1. Перед началом #

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

Рекомендуется следовать этому руководству по быстрому запуску в непроизводственной среде.

I.3.4.1.1. Предварительные условия #
  • Рабочий экземпляр Tantor BE

  • Установлены клиентские утилиты PostgreSQL

Примечание

Если вы работаете не под суперпользователем, убедитесь, что можете установить расширение **pgcrypto** в вашей исходной базе данных для быстрого старта.

I.3.4.2. Подготовка pg_anon #

git clone https://github.com/TantorLabs/pg_anon.git pg_anon
cd pg_anon
virtualenv venv
source venv/bin/activate
pip install -r requirements.txt
python3 -m pg_anon --version

I.3.4.3. Подготовка среды базы данных #

Создайте пользователя БД для руководства по быстрому старту

sudo su - postgres -c "psql -p 5432 -U postgres -c \"CREATE USER anon_test_user WITH PASSWORD 'mYy5RexGsZ' SUPERUSER;\""

Подготовьте SQL-скрипт для инициализации баз данных

cat > /tmp/db_env.sql << 'EOL'
DROP DATABASE IF EXISTS pg_anon_quick_start_source_db;
CREATE DATABASE pg_anon_quick_start_source_db
WITH
OWNER = anon_test_user
ENCODING = 'UTF8'
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
template = template0;

DROP DATABASE IF EXISTS pg_anon_quick_start_target_db;
CREATE DATABASE pg_anon_quick_start_target_db
WITH
OWNER = anon_test_user
ENCODING = 'UTF8'
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
template = template0;
EOL

Инициализируйте исходную и целевую базы данных

sudo chown postgres:postgres /tmp/db_env.sql
sudo su - postgres -c "psql -p 5432 -U postgres -f /tmp/db_env.sql"

Загрузите тестовую среду в исходную базу данных

cp $(pwd)/tests/sql/init_env.sql /tmp/init_env.sql
sudo chown postgres:postgres /tmp/init_env.sql
sudo su - postgres -c "psql -p 5432 -d pg_anon_quick_start_source_db -U postgres -f /tmp/init_env.sql"

I.3.4.4. Инициализация cлужебной схемы для pg_anon #

python3 -m pg_anon init \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_source_db \
    --db-host=127.0.0.1 \
    --db-port=5432

I.3.4.5. Сканирование вашей исходной базы данных #

python3 -m pg_anon create-dict \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_source_db \
    --db-host=127.0.0.1 \
    --db-port=5432 \
    --meta-dict-file=tests/input_dict/test_meta_dict.py \
    --output-sens-dict-file=test_sens_dict_output.py \
    --output-no-sens-dict-file=test_no_sens_dict_output.py \
    --processes=2

I.3.4.6. Визуализация правил анонимизации #

Запустите pg_anon в режиме view-fields, чтобы увидеть, какие поля будут анонимизированы, а какие поля будут выгружены как есть.

python3 -m pg_anon view-fields \
    --db-host=127.0.0.1 \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_source_db \
    --db-port=5432 \
    --prepared-sens-dict-file=test_sens_dict_output.py \
    --fields-count=20

Запустите pg_anon в режиме view-data, чтобы просмотреть анонимизированные данные в определённой таблице.

python3 -m pg_anon view-data \
    --db-host=127.0.0.1 \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_source_db \
    --db-port=5432 \
    --prepared-sens-dict-file=test_sens_dict_output.py \
    --schema-name=public \
    --table-name=contracts \
    --limit=10 \
    --offset=0

I.3.4.7. Создание анонимизированной резервной копии #

python3 -m pg_anon dump \
    --db-host=127.0.0.1 \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_source_db \
    --db-port=5432 \
    --prepared-sens-dict-file=test_sens_dict_output.py \
    --output-dir=/tmp/quick_start_dump \
    --clear-output-dir

I.3.4.8. Восстановление анонимизированной резервной копии в целевую базу данных #

python3 -m pg_anon restore \
    --db-host=127.0.0.1 \
    --db-port=5432 \
    --db-user=anon_test_user \
    --db-user-password=mYy5RexGsZ \
    --db-name=pg_anon_quick_start_target_db \
    --input-dir=/tmp/quick_start_dump \
    --drop-custom-check-constr \
    --verbose=debug

I.3.5. Установка и настройка #

Вы можете использовать несколько вариантов для установки pg_anon:

I.3.5.1. Перед установкой #

pg_anon предоставляет 2 способа запуска: CLI и REST API

Сервис REST API является необязательным для установки. Этот сервис предназначен для интеграции функциональности pg_anon в любые системы или конвейеры с помощью HTTP-запросов. Он работает как тонкая обёртка вокруг CLI-версии pg_anon. Вызовы REST API подготавливают параметры для CLI и запускают CLI-версию pg_anon в фоновом режиме.

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

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

Примечание

Не подходит для полностью автономной работы.

Все журналы выполнения операций и информация будут сохраняться в каталоге /path_to_pg_anon/runs. Все дампы будут сохраняться в каталоге /path_to_pg_anon/output. Если служба REST API масштабируется, необходимо создать символическую ссылку на этот каталог на общем диске. Это требуется, потому что операции восстановления также читают дампы из /path_to_pg_anon/output.

I.3.5.2. С помощью db_extension_installer.sh локально из скачанного пакета #

  1. Скачайте пакет pg_anon, подходящий для вашей операционной системы, с сайта nexus-public.

  2. Скачайте установочный скрипт db_extension_installer.sh и сделайте его исполняемым:

    wget https://public.tantorlabs.ru/db_extension_installer.sh && \
    chmod +x db_extension_installer.sh
    
  3. Выполните установку pg_anon с помощью db_extension_installer.sh из скачанного пакета:

    ./db_extension_installer.sh \
      --from-file=<path to pg_anon package>
    

I.3.5.3. С помощью db_extension_installer.sh автоматически из репозитория пакетов #

  1. Скачайте установочный скрипт db_extension_installer.sh и сделайте его исполняемым:

    wget https://public.tantorlabs.ru/db_extension_installer.sh && \
    chmod +x db_extension_installer.sh
    
  2. Установите значение переменной окружения NEXUS_URL:

    export NEXUS_URL="nexus-public.tantorlabs.ru"
    
  3. Выполните установку pg_anon с помощью db_extension_installer.sh со следующими параметрами:

    ./db_extension_installer.sh \
      --database-type=tantor \
      --edition=all \
      --extension=pg_anon
    

I.3.5.4. Из репозитория GitHub (Python) #

  1. Установите Python 3, если он не установлен: sudo apt-get install python3.11 (для Ubuntu)

  2. Клонируйте репозиторий: git clone https://github.com/TantorLabs/pg_anon.git

  3. Перейдите в каталог проекта: cd pg_anon

  4. Настроить виртуальную среду:

    • Установите виртуальное окружение: python3 -m venv venv

    • Активируйте виртуальное окружение: source venv/bin/activate

  5. Установите зависимости: pip install -r requirements.txt

  6. (Необязательно) Для использования службы REST API установите её зависимости: pip install -r rest_api/requirements.txt

I.3.5.5. Настройка pg_anon #

Чтобы указать пользовательские утилиты pg_dump и pg_restore, используйте параметры --pg-dump и --pg-restore.

Доступна также расширенная настройка:

  • CLI - используйте параметр запуска --config

  • REST API - конфигурационный файл должен быть размещён по адресу /path_to_pg_anon/config.yml

pg-utils-versions:
  <postgres_major_version>:
    pg_dump: "/path/to/<postgres_major_version>/pg_dump"
    pg_restore: "/path/to/<postgres_major_version>/pg_restore"
  <another_postgres_major_version>:
    pg_dump: "/path/to/<postgres_major_version>/pg_dump"
    pg_restore: "/path/to/<postgres_major_version>/pg_restore"
  default:
    pg_dump: "/path/to/default_postgres_version/pg_dump"
    pg_restore: "/path/to/default_postgres_version/pg_restore"

Например, вы можете указать конфигурацию для Tantor BE 15 и 17:

pg-utils-versions:
  15:
    pg_dump: "/opt/tantor/db/15/bin/pg_dump"
    pg_restore: "/opt/tantor/db/15/bin/pg_restore"
  17:
    pg_dump: "/opt/tantor/db/17/bin/pg_dump"
    pg_restore: "/opt/tantor/db/17/bin/pg_restore"
  default:
    pg_dump: "/opt/tantor/db/17/bin/pg_dump"
    pg_restore: "/opt/tantor/db/17/bin/pg_restore"

Если текущая версия Tantor BE не соответствует ни одной из версий в этой конфигурации, будут использоваться утилиты из секции по умолчанию. Например, pg_anon может быть запущен с этой конфигурацией на Tantor BE 16. В этом случае будут использоваться pg_dump 17 и pg_restore 17.

I.3.5.6. Запуск REST API #

Выполнить команду службы:

python -m uvicorn rest_api.api:app --host 0.0.0.0 --port 8000 --workers=3
  • Рекомендуемое количество рабочих процессов = 2 * CPU_CORES + 1

  • Документация OpenAPI сервиса будет доступна по адресу - http://0.0.0.0:8000/docs#/

  • Также вы можете посмотреть документацию по API

I.3.6. Как это работает #

I.3.6.1. Анонимизация (маскирование) #

Диаграмма ниже иллюстрирует, как данные передаются из исходной БД в целевую БД.

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

Диаграмма I.1. Dump-Resore-Terms.drawio.png

Dump-Resore-Terms.drawio.png

Доверенный администратор запускает pg_anon с учетными данными для исходной БД. Используя подготовленный и одобренный словарь конфиденциальных данных, pg_anon создает анонимизированный дамп в указанной директории. Словарь должен быть создан заранее и проверен службой безопасности.

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

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

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

I.3.6.2. Какую работу выполняет pg_anon внутри во время дампа и восстановления? Самое простое представление. #

I.3.6.2.1. Например, у нас есть данные, которые мы хотим анонимизировать: #
  1. Создайте исходную таблицу:

create table users (
    id bigserial,
    email text,
    login text
);

-- Checking the contents of the source table
select * from users;
>>
    id |  email  | login 
   ----+---------+-------
  1. Заполните исходную таблицу:

insert into users (email, login)
select
 'user' || generate_series(1001, 1020) || '@example.com',
 'user' || generate_series(1001, 1020);

-- Checking the contents of the source table
select * from users;
>>
    id |    email         |  login   
   ----+----------------------+----------
     1 | user1001@example.com | user1001
     2 | user1002@example.com | user1002
    ...

Поле ‘email’ содержит конфиденциальные данные. Нам нужно анонимизировать их.

I.3.6.2.2. Каков процесс создания дампа с маскированием? #
  1. Дамп данных исходной таблицы в CSV-файл (без маскирования):

copy (
    select *
    from users
) to '/tmp/users.csv' with csv;
cat /tmp/users.csv
>>
   1,user1001@example.com,user1001
   2,user1002@example.com,user1002
   ...
  1. Маскирование содержимого исходной таблицы:

select
   id,
   md5(email) || '@abc.com' as email, -- hashing the email (masking rule in prepared sens dict file)
   login
from users;
>>
    id |                email                     |  login   
   ----+------------------------------------------+----------
     1 | 385513d80895c4c5e19c91d1df9eacae@abc.com | user1001
     2 | 9f4c0c30f85b0353c4d5fe3c9cc633e3@abc.com | user1002
    ...
  1. Дамп данных исходной таблицы в CSV-файл (с маскированием):

copy (
  select
    id,
    md5(email) || '@abc.com' as email, -- hashing the email (masking rule in prepared sens dict file)
    login
  from users
) to '/tmp/users_anonymized.csv' with csv;
cat /tmp/users_anonymized.csv
>>
   1,385513d80895c4c5e19c91d1df9eacae@abc.com,user1001
   2,9f4c0c30f85b0353c4d5fe3c9cc633e3@abc.com,user1002
   ...

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

I.3.6.2.3. Каков проходит процесс восстановления дампа с замаскированными данными? #
  1. Воспроизведение структуры. Создание таблицы приемника:

create table users_anonymized (
    id bigserial,
    email text,
    login text
);

-- Checking the contents of the target table
select * from users_anonymized;
>>
    id |  email  | login 
   ----+---------+-------
  1. Загрузка данных из дампа исходной таблицы (CSV-файл) в таблицу приемник:

copy users_anonymized
from '/tmp/users_anonymized.csv'
with csv;

-- Checking the contents of the target table
select * from users_anonymized;
>>
    id |                email                     |  login   
   ----+------------------------------------------+----------
     1 | 385513d80895c4c5e19c91d1df9eacae@abc.com | user1001
     2 | 9f4c0c30f85b0353c4d5fe3c9cc633e3@abc.com | user1002
    ...
I.3.6.2.4. Отличия между оригинальной работой pg_anon и данной реализацией #
  • pg_anon работает со всей базой данных (не только с одной таблицей)

  • pg_anon использует файлы .bin.gz для сохранения данных (не csv)

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

I.3.7. Операции #

I.3.7.1. Init #

Этот режим создает схему anon_funcs в исходной базе данных и загружает предопределенные SQL-функции из init.sql. Эти функции необходимы для обработки данных в исходной базе данных.

I.3.7.1.1. Запустить пример #
python -m pg_anon init \
                  --db-user=postgres \
                  --db-user-password=postgres \
                  --db-name=source_db
I.3.7.1.2. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

Опция Обязательно Описание
--db-host Да Хост базы данных.
--db-port Нет Порт базы данных.
--db-name Да Имя базы данных.
--db-user Да Пользователь базы данных.
--db-user-password Нет Пароль пользователя базы данных.
--db-passfile Нет Путь к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-file Нет Путь к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-file Нет Путь к файлу SSL-сертификата клиента.
--db-ssl-ca-file Нет Путь к сертификату CA, используемому для проверки сертификата сервера.

I.3.7.2. Scan #

Операция сканирования анализирует вашу базу данных Tantor BE для обнаружения потенциально конфиденциальных данных и создания файлов словарей. Она используется для дампа и повторного сканирования.

I.3.7.2.1. Предварительные условия #
  • Вручную созданный мета-словарь

  • Режим init уже был выполнен для исходной базы данных

I.3.7.2.2. Использование #

Чтобы просканировать исходную базу данных и создать словарь для дампа, запустите pg_anon в режиме create-dict. Вам потребуется:

  • мета-словарь файл с правилами сканирования.

python pg_anon.py create-dict \
                  --db-user=postgres \
                  --db-user-password=postgres \
                  --db-name=test_source_db \
                  --meta-dict-file=test_meta_dict.py \
                  --prepared-sens-dict-file=test_sens_dict_output_previous_use.py \
                  --prepared-no-sens-dict-file=test_no_sens_dict_output_previous_use.py \
                  --output-sens-dict-file=test_sens_dict_output.py \
                  --output-no-sens-dict-file=test_no_sens_dict_output.py \
                  --processes=2
I.3.7.2.3. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--config Нет Путь к файлу конфигурации, который может указывать утилиты pg_dump и pg_restore. (по умолчанию: нет)
--processes Нет Количество процессов, используемых для многопроцессорных операций. (по умолчанию: 4)
--db-connections-per-process Нет Количество подключений к базе данных на процесс для операций ввода-вывода. (по умолчанию: 4)
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

Опция Обязательно Описание
--db-host Да Хост базы данных.
--db-port Нет Порт базы данных.
--db-name Да Имя базы данных.
--db-user Да Пользователь базы данных.
--db-user-password Нет Пароль пользователя базы данных.
--db-passfile Нет Путь к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-file Нет Путь к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-file Нет Путь к файлу SSL-сертификата клиента.
--db-ssl-ca-file Нет Путь к сертификату CA, используемому для проверки сертификата сервера.

Параметры режима Create-dict (сканирование)

Опция Обязательно Описание
--meta-dict-file Да Входной файл или список файлов содержит мета-словарь, который был подготовлен вручную. В случае конфликта правил приоритет имеют правила из последнего файла в списке.
--prepared-sens-dict-file Нет Входной файл или список файлов содержит чувствительный словарь, который был получен при предыдущем использовании опции --output-sens-dict-file или подготовлен вручную. В случае конфликта правил приоритет имеют правила из последнего файла в списке.
--prepared-no-sens-dict-file Нет Входной файл или список файлов содержит нечувствительный словарь, который был получен при предыдущем использовании опции --output-no-sens-dict-file или подготовлен вручную. В случае коллизии правил приоритет имеют правила из последнего файла в списке.
--output-sens-dict-file Да Путь к выходному файлу для сохранения чувствительного словаря
--output-no-sens-dict-file Нет Путь к выходному файлу для сохранения нечувствительного словаря
--scan-mode Нет Определяет, сканировать ли все данные или только их часть [full, partial] (по умолчанию partial)
--scan-partial-rows Нет В --scan-mode partial определяет количество строк для сканирования (по умолчанию 10000). Фактическое количество строк может быть меньше после получения уникальных значений
--save-dicts Нет Дублирует все входные и выходные словари в каталог runs. Это может быть полезно для отладки или интеграции.

I.3.7.3. Dump #

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

Примечание

Этот резервный файл может быть восстановлен только с помощью pg_anon и не может быть восстановлен с помощью pg_restore

I.3.7.3.1. Предварительные условия #
  • Схема anon_funcs с функциями анонимизации должна уже существовать. Смотрите режим Init.

  • Необходимо заранее подготовить конфиденциальный словарь, содержащий данные о полях базы данных и их правилах анонимизации. Смотрите режим create-dict (сканирование).

I.3.7.3.2. Полный дамп (dump) #

Создаёт резервную копию, содержащую как структуру базы данных, так и анонимизированные данные.

Эту резервный копию можно восстановить с помощью следующих режимов:

Запустить пример

python pg_anon.py dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --prepared-sens-dict-file=sens_dict.py
I.3.7.3.3. Дамп структуры (sync-struct-dump) #

Создает резервную копию, содержащую только структуру базы данных без анонимизированных данных.

Эта резервная копия может быть восстановлена в режиме:

Этот режим полезен при использовании вместе с режимом дампа данных (sync-data-dump).

Запустить пример

python pg_anon.py sync-struct-dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --output-dir=test_sync_struct_dump \
                 --prepared-sens-dict-file=sens_dict.py
I.3.7.3.4. Дамп данных (sync-data-dump) #

Создать резервную копию, содержащую только анонимизированные данные без структуры базы данных.

Эта резервная копия может быть восстановлена в режиме:

Этот режим может быть полезен для планирования синхронизации базы данных, например, с использованием cron.

Запустить пример

python pg_anon.py sync-data-dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --output-dir=test_sync_data_dump \
                 --prepared-sens-dict-file=sens_dict.py
I.3.7.3.5. Создать частичную дамп-копию #

Частичные дампы используются для создания резервной копии с исключением определённых таблиц из исходной базы данных.

Частичное дамп может выполняться во всех режимах дампа:

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

Запустить пример

Выгрузить только нужные таблицы (белый список)

python pg_anon.py dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --output-dir=partial_dump_white_list \
                 --prepared-sens-dict-file=sens_dict.py
                 --partial-tables-dict-file=include_tables.py

Выгрузить все таблицы, кроме некоторых указанных (чёрный список)

python pg_anon.py dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --output-dir=partial_dump_black_list \
                 --prepared-sens-dict-file=sens_dict.py
                 --partial-tables-exclude-dict-file=exclude_tables.py

Выгрузить только указанные таблицы, исключив некоторые из них (белый список + черный список)

python pg_anon.py dump \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --output-dir=partial_dump_white_list_and_black_list \
                 --prepared-sens-dict-file=sens_dict.py
                 --partial-tables-dict-file=include_tables.py
                 --partial-tables-exclude-dict-file=exclude_tables.py
I.3.7.3.6. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--config Нет Путь к файлу конфигурации, который может указывать утилиты pg_dump и pg_restore. (по умолчанию: нет)
--db-connections-per-process Нет Количество подключений к базе данных на процесс для операций ввода-вывода. (по умолчанию: 4)
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

Опция Обязательно Описание
--db-host Да Хост базы данных.
--db-port Нет Порт базы данных.
--db-name Да Имя базы данных.
--db-user Да Пользователь базы данных.
--db-user-password Нет Пароль пользователя базы данных.
--db-passfile Нет Путь к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-file Нет Путь к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-file Нет Путь к файлу SSL-сертификата клиента.
--db-ssl-ca-file Нет Путь к сертификату CA, используемому для проверки сертификата сервера.

Параметры режима дампа

Опция Обязательно Описание
--prepared-sens-dict-file Да Входной файл или список файлов содержит чувствительный словарь, который был сгенерирован в режиме create-dict (сканирование) или создан вручную. В случае конфликта правил приоритет имеют правила из последнего файла в списке
--partial-tables-dict-file Нет Входной файл или список файлов содержит словарь таблиц для включения определённых таблиц в дамп. Все таблицы, не перечисленные в этих файлах, будут исключены. Эти файлы должны быть подготовлены вручную (работает как белый список).
--partial-tables-exclude-dict-file Нет Входной файл или список файлов содержит словарь таблиц для исключения определённых таблиц из дампа. Все таблицы, перечисленные в этих файлах, будут исключены. Эти файлы должны быть подготовлены вручную (используются как чёрный список)
--dbg-stage-1-validate-dict Нет Проверить словарь, показать таблицы и выполнить SQL запросы без экспорта данных (по умолчанию: false)
--dbg-stage-2-validate-data Нет Проверить данные, показать таблицы и выполнить SQL-запросы с экспортом данных в подготовленной базе данных (по умолчанию: false)
--dbg-stage-3-validate-full Нет Включает всю логику с limit в SQL-запросах (по умолчанию: false)
--clear-output-dir Нет Очищает выходной каталог от предыдущих дампов или других файлов. (по умолчанию: false)
--pg-dump Нет Путь к инструменту Postgres pg_dump (по умолчанию /usr/bin/pg_dump).
--pg-dump-optionsНетДополнительные параметры, передаваемые непосредственно утилите pg_dump. Пример: "--no-comments --encoding=LATIN1".
--output-dir Нет Каталог для вывода файлов дампа. (по умолчанию "")
--ignore-privileges Нет Игнорировать привилегии из исходной базы данных.
--save-dicts Нет Дублирует все входные словари в каталог runs. Это может быть полезно для отладки или интеграции.

I.3.7.4. Restore #

Этот режим восстанавливает анонимизированную резервную копию, созданную с помощью pg_anon в режиме Dump.

Примечание

Восстановить можно только резервные копии, созданные с помощью pg_anon. Резервные копии, созданные с помощью pg_dump, нельзя восстановить.

I.3.7.4.1. Полное восстановление (restore) #

Восстанавливает как структуру базы данных, так и данные.

Предварительные требования

  • Дамп или частичный дамп, созданный с помощью pg_anon в режиме Полный дамп (dump).

  • Целевая база данных должна быть пустой, или можно использовать опции --clean-db / --drop-db.

Запустить пример

python pg_anon.py restore \
                  --db-host=127.0.0.1 \
                  --db-user=postgres \
                  --db-user-password=postgres \
                  --db-name=target_db \
                  --input-dir=path/to/my_full_dump \
                  --verbose=debug
I.3.7.4.2. Восстановление структуры (sync-struct-restore) #

Восстанавливает только структуру базы данных.

Предварительные требования

Запустить пример

python pg_anon.py sync-struct-restore \
                  --db-host=127.0.0.1 \
                  --db-user=postgres \
                  --db-user-password=postgres \
                  --db-name=target_db \
                  --input-dir=path/to/my_sync_struct_dump \
                  --verbose=debug
I.3.7.4.3. Восстановление данных (sync-data-restore) #

Восстанавливает только данные.

Предварительные требования

Запустить пример

python pg_anon.py sync-data-restore \
                  --db-host=127.0.0.1 \
                  --db-user=postgres \
                  --db-user-password=postgres \
                  --db-name=target_db \
                  --input-dir=path/to/my_sync_data_dump \
                  --verbose=debug
I.3.7.4.4. Создать частичное восстановление #

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

Частичное восстановление можно выполнять во всех режимах восстановления:

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

Запустить пример

Восстановить только необходимые таблицы (белый список)

python pg_anon.py restore \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --input-dir=partial_dump_white_list \
                 --partial-tables-dict-file=include_tables.py

Выгрузить все таблицы, кроме некоторых указанных (чёрный список)

python pg_anon.py restore \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --input-dir=partial_dump_black_list \
                 --partial-tables-exclude-dict-file=exclude_tables.py

Выгрузить только указанные таблицы, исключив некоторые из них (белый список + черный список)

python pg_anon.py restore \
                 --db-host=127.0.0.1 \
                 --db-user=postgres \
                 --db-user-password=postgres \
                 --db-name=source_db \
                 --input-dir=partial_dump_white_list_and_black_list \
                 --partial-tables-dict-file=include_tables.py
                 --partial-tables-exclude-dict-file=exclude_tables.py
I.3.7.4.5. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--config Нет Путь к файлу конфигурации, который может указывать утилиты pg_dump и pg_restore. (по умолчанию: нет)
--processes Нет Количество процессов, используемых для многопроцессорных операций. (по умолчанию: 4)
--db-connections-per-process Нет Количество подключений к базе данных на процесс для операций ввода-вывода. (по умолчанию: 4)
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

Опция Обязательно Описание
--db-host Да Хост базы данных.
--db-port Нет Порт базы данных.
--db-name Да Имя базы данных.
--db-user Да Пользователь базы данных.
--db-user-password Нет Пароль пользователя базы данных.
--db-passfile Нет Путь к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-file Нет Путь к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-file Нет Путь к файлу SSL-сертификата клиента.
--db-ssl-ca-file Нет Путь к сертификату CA, используемому для проверки сертификата сервера.

Параметры режима восстановления

Опция Обязательно Описание
--input-dir Да Путь к каталогу, содержащему файлы дампа, созданные в режиме дампа.
--partial-tables-dict-file Нет Вход Входной файл или список файлов содержит словарь таблиц для включения определённых таблиц в дамп. Все таблицы, не перечисленные в этих файлах, будут исключены. Эти файлы должны быть подготовлены вручную (работают как белый список).
--partial-tables-exclude-dict-file Нет Вход Входной файл или список файлов содержит словарь таблиц для исключения определённых таблиц из дампа. Все таблицы, перечисленные в этих файлах, будут исключены. Эти файлы должны быть подготовлены вручную (используются как чёрный список)
--disable-checks Нет Отключить проверки дискового пространства и версии Tantor BE (по умолчанию false)
--seq-init-by-max-value Нет Инициализировать последовательности на основе максимальных значений. В противном случае последовательности будут инициализированы на основе значений исходной базы данных.
--drop-custom-check-constr Нет Удаляет все ограничения CHECK, которые содержат пользовательские процедуры, чтобы избежать снижения производительности при загрузке данных.
--pg-restore Нет Путь к инструменту Postgres pg_restore.
--pg-restore-optionsНетДополнительные параметры, передаваемые непосредственно утилите pg_restore. Пример: "--no-comments --no-table-access-method".
--clean-db Нет Очищает объекты базы данных перед восстановлением (если они существуют в дампе). Взаимно исключается с --drop-db.
--drop-db Нет Удалить целевую базу данных перед восстановлением. Взаимоисключается с --clean-db.
--ignore-privileges Нет Игнорировать привилегии из исходной базы данных.
--save-dicts Нет Дублирует все входные словари в каталог runs. Это может быть полезно для отладки или интеграции.

I.3.7.5. View Fields #

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

I.3.7.5.1. Предварительные условия #
  • Схема anon_funcs с функциями анонимизации должна уже существовать. Смотрите режим Init.

  • Необходимо заранее подготовить конфиденциальный словарь, содержащий данные о полях базы данных и их правилах анонимизации. Смотрите режим create-dict (сканирование).

I.3.7.5.2. Запустить пример #
   python pg_anon.py view-fields \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=source_db \
                     --prepared-sens-dict-file=sens_dict.py

Примечание

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

Этот лимит контролируется опцией --fields-count (по умолчанию: 5000 полей). Чтобы избежать превышения этого лимита, увеличьте значение --fields-count или используйте опции фильтрации: --schema-name, --schema-mask, --table-name, --table-mask.

I.3.7.5.3. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--config Нет Путь к файлу конфигурации, который может указывать утилиты pg_dump и pg_restore. (по умолчанию: нет)
--processes Нет Количество процессов, используемых для многопроцессорных операций. (по умолчанию: 4)
--db-connections-per-process Нет Количество подключений к базе данных на процесс для операций ввода-вывода. (по умолчанию: 4)
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

ОпцияОбязательноОписание
--db-hostДаХост базы данных.
--db-portНетПорт базы данных.
--db-nameДаИмя базы данных.
--db-userДаПользователь базы данных.
--db-user-passwordНетПароль пользователя базы данных.
--db-passfileНетПуть к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-fileНетПуть к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-fileНетПуть к файлу клиентского SSL-сертификата.
--db-ssl-ca-fileНетПуть к сертификату удостоверяющего центра (CA), используемому для проверки сертификата сервера.

Параметры режима просмотра полей

Опция Обязательно Описание
--prepared-sens-dict-file Да Путь к входному файлу или списку файлов, содержащих чувствительный словарь, который был сгенерирован в режиме create-dict (сканирование) или создан вручную. В случае конфликта правил приоритет имеют правила из последнего файла в списке.
--view-only-sensitive-fields Нет Отображает только конфиденциальные поля. (по умолчанию: все поля)
--fields-count Нет Максимальное количество полей для обработки при выводе (по умолчанию: 5000)
--schema-name Нет Фильтровать по имени схемы
--schema-mask Нет Фильтровать по имени схемы с использованием регулярного выражения
--table-name Нет Фильтрация по имени таблицы
--table-mask Нет Фильтрация по имени таблицы с использованием регулярного выражения
--json Нет Выводит результаты в формате JSON вместо таблицы.

I.3.7.6. View Data #

Этот режим отображает анонимизированные данные таблицы без создания дампа.

I.3.7.6.1. Предварительные условия #
  • Схема anon_funcs с функциями анонимизации должна уже существовать. Смотрите режим Init.

  • Необходимо заранее подготовить конфиденциальный словарь, содержащий данные о полях базы данных и их правилах анонимизации. Смотрите режим create-dict (сканирование).

I.3.7.6.2. Запустить пример #
   python pg_anon.py view-data \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=source_db \
                     --prepared-sens-dict-file=sens_dict.py \
                     --schema-name=public \
                     --table-name=users \
                     --limit=10 \
                     --offset=0
I.3.7.6.3. Опции #

Общие параметры pg_anon

Опция Обязательно Описание
--config Нет Путь к файлу конфигурации, который может указывать утилиты pg_dump и pg_restore. (по умолчанию: нет)
--processes Нет Количество процессов, используемых для многопроцессорных операций. (по умолчанию: 4)
--db-connections-per-process Нет Количество подключений к базе данных на процесс для операций ввода-вывода. (по умолчанию: 4)
--verbose Нет Устанавливает уровень подробности журналирования: info, debug, error. (по умолчанию: info)
--debug Нет Включает режим отладки (эквивалентно --verbose=debug) и добавляет дополнительные отладочные журналы. (по умолчанию: false)

Параметры конфигурации базы данных

Опция Обязательно Описание
--db-host Да Хост базы данных.
--db-port Нет Порт базы данных.
--db-name Да Имя базы данных.
--db-user Да Пользователь базы данных.
--db-user-password Нет Пароль пользователя базы данных.
--db-passfile Нет Путь к файлу, содержащему пароль, используемый для аутентификации.
--db-ssl-key-file Нет Путь к файлу SSL-ключа клиента для защищённых подключений.
--db-ssl-cert-file Нет Путь к файлу SSL-сертификата клиента.
--db-ssl-ca-file Нет Путь к сертификату CA, используемому для проверки сертификата сервера.

Параметры режима просмотра данных

Опция Обязательно Описание
--prepared-sens-dict-file Да Путь к входному файлу или списку файлов, содержащих чувствительный словарь, который был сгенерирован в режиме create-dict (сканирование) или создан вручную. В случае конфликта правил приоритет имеют правила из последнего файла в списке.
--schema-name Да Имя схемы.
--table-name Да Имя таблицы.
--limit Нет Количество отображаемых строк. (по умолчанию: 100)
--offset Нет Смещение строки для постраничного вывода. (по умолчанию: 0)
--json Нет Выводит результаты в формате JSON вместо таблицы.

I.3.8. Схемы словарей #

I.3.8.1. Мета-словарь #

Мета-словарь определяет правила, используемые pg_anon для обнаружения чувствительных полей во время режима create-dict (сканирования)

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

Во время сканирования pg_anon анализирует все схемы базы данных, таблицы и поля.

Мета-словарь позволяет вам:

  • включить или исключить определённые объекты

  • обнаруживать чувствительные поля по:

    • имена полей

    • шаблоны данных (регулярные выражения)

    • точные или частичные константы

    • пользовательские функции на Python

    • Условия фильтрации SQL

    • выберите, какие типы PostgreSQL следует сканировать

    • указать функции анонимизации для каждого типа данных

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

В конце показана полная объединённая схема.

I.3.8.1.1. Приоритет сканирования #
Приоритет Раздел мета-словаря Обязательный Описание
1 skip_rules + include_rules Нет Сузить набор полей для сканирования
2 Поля из чувствительного словаря + field + поля из нечувствительного словаря Нет Сопоставление по именам полей. Не анализирует данные внутри таблиц
3 sens_pg_types Нет Сопоставление по типу поля. Типы, не включённые в этот раздел, игнорируются
4 data_sql_condition Нет Сужает набор данных для сканирования для конкретных таблиц с помощью SQL-условий
5 data_func Нет Сопоставление данных с помощью пользовательских функций сканирования данных
6 data_const Нет Сопоставление данных по постоянным значениям
7 data_regex Нет Сопоставление данных с помощью регулярных выражений
8 funcs Нет Назначить функции анонимизации в соответствии с определённым типом данных

Диаграмма I.2. scan_workflow.png

scan_workflow.png

I.3.8.1.2. skip_rules #

Назначение

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

Схема

{
    "skip_rules": [
        {
            "schema": "<schema_name: string>",             # Skip this schema from scanning
            "schema_mask": "<schema_regex_mask: string>",  # Or skip from scanning schemas matching regex pattern
            "table": "<table_name: string>",               # Skip from scanning only this table
            "table_mask": "<table_regex_mask: string>",    # Or skip from scanning tables matching regex pattern
            "fields": [  # Skip from scanning fields of tables
                "<field_name: string>"
            ]
        }
    ]
}

Комбинации правил

  1. schema или schema_mask — обязательно

    • Вы должны указать либо schema, либо schema_mask

    • Это определяет, где применяется правило.

  2. table или table_mask — необязательно

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

    • Если указаны table или table_mask → правило применяется только к этим таблицам.

    • Если оба опущены → правило применяется ко всей схеме.

  3. fields — необязательно

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

    • Если указаны fields → пропускаются только эти поля.

    • Если fields опущен → вся таблица пропускается.

    • И если table не указана → вся схема пропускается.

Использование этого раздела

Пример мета-словаря

{
    "skip_rules": [
        {
          "schema_msk": "^tmp.*"
        },
      {
        "schema": "ecommerce",
        "table_mask": "^client_.*"
      },
      {
        "schema": "public",
        "fields": ["currency", "id", "employee_id"]
      },
      {
        "schema": "ecommerce",
        "table": "orders",
        "fields": ["count"]
      }
    ]
}

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Пропущено
public employees id Да
public employees full_name Нет
public employees email Нет
public employees password Нет
public employees phone Нет
public employees hire_date Нет
public salaries employee_id Нет
public salaries monthly_salary Нет
public salaries currency Да
ecommerce orders product_id Нет
ecommerce orders client_name Да
ecommerce orders client_phone Да
ecommerce orders client_delivery_address Да
ecommerce orders count Да
ecommerce orders created Нет
ecommerce orders status Нет
tmp_some_1 tbl_1 content Да
tmp_some_2 tbl_2 content Да
I.3.8.1.3. include_rules #

Назначение

Ограничить сканирование определёнными схемами/таблицами/полями. Полезно, когда:

  • сканирование только части большой базы данных

  • отладка правил обнаружения

  • выполнение сфокусированных сканирований

Схема

{
    "include_rules": [
        {
            "schema": "<schema_name: string>",             # Include only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or include schemas matching regex pattern
            "table": "<table_name: string>",               # Include only this table
            "table_mask": "<table_regex_mask: string>",    # Or include tables matching regex pattern
            "fields": [  # Include only this fields of tables for scanning
                "<field_name: string>"
            ]
        }
    ]
}

Правила комбинации

  1. schema или schema_mask — обязательно

    • Вы должны указать либо schema, либо schema_mask

    • Это определяет, где применяется правило.

  2. table или table_mask — необязательно

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

    • Если указаны table или table_mask → правило применяется только к этим таблицам.

    • Если оба опущены → правило применяется ко всей схеме.

  3. fields — необязательно

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

    • Если указаны fields → пропускаются только эти поля.

    • Если fields опущен → вся таблица пропускается.

    • И если table не указана → вся схема пропускается.

Использование этого раздела

Пример мета-словаря

{
    "include_rules": [
        {
          "schema_msk": "^tmp.*"
        },
      {
        "schema": "ecommerce",
        "table_mask": "^client_.*"
      },
      {
        "schema": "public",
        "fields": ["currency", "id", "employee_id"]
      },
      {
        "schema": "ecommerce",
        "table": "orders",
        "fields": ["count"]
      }
    ]
}

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Пропущено
public employees id Нет
public employees full_name Да
public employees email Да
public employees password Да
public employees phone Да
public employees hire_date Да
public salaries employee_id Да
public salaries monthly_salary Да
public salaries currency Нет
ecommerce orders product_id Да
ecommerce orders client_name Нет
ecommerce orders client_phone Нет
ecommerce orders client_delivery_address Нет
ecommerce orders count Нет
ecommerce orders created Да
ecommerce orders status Да
tmp_some_1 tbl_1 content Нет
tmp_some_2 tbl_2 content Нет
I.3.8.1.4. field #

Назначение

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

Полезно, когда уже известно, что поля содержат конфиденциальные данные (например, электронная почта, пароль)

Схема

{
    "field": {
        "rules": [
            "<field_name_regex: string>",
        ],
        "constants": [
            "<field_name: string>",
        ]
    }
}
Ключ Значение
rules Список шаблонов регулярных выражений. Имена полей, соответствующие этим шаблонам, всегда считаются конфиденциальными.
constants Точные имена полей, которые следует считать конфиденциальными.

Использование этого раздела

Пример мета-словаря

{
    "field": {
        "rules": [
            "^client_",
            ".*phone.*"
        ],
        "constants": [
            "password",
            "email"
        ]
    }
}

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Чувствительное Правило
public employees id Нет -
public employees full_name Нет -
public employees email Да email
public employees password Да password
public employees phone Да .*phone.*
public employees hire_date Нет -
public salaries employee_id Нет -
public salaries monthly_salary Нет -
public salaries currency Нет -
ecommerce orders product_id Нет -
ecommerce orders client_name Да ^client_
ecommerce orders client_phone Да .*phone.*
ecommerce orders client_delivery_address Да ^клиент_
ecommerce orders count Нет -
ecommerce orders created Нет -
ecommerce orders status Нет -
I.3.8.1.5. sens_pg_types #

Назначение

Определяет, какие типы PostgreSQL будут сканироваться. Типы полей, не включённые в этот список, не сканируются.

Если опущено или пусто → используются типы по умолчанию: text, character, varchar, mvarchar, json, integer, bigint

Схема

{
    "sens_pg_types": [
        "<field_type: string>",
    ]
}

Использование этого раздела

Пример мета-словаря

{
    "sens_pg_types": [
        "text",
        "integer",
        "bigint",
        "numeric(10,2)",
        "varchar",
        "mchar",
        "json"
    ]
}

Приоритеты разрешения типа поля:

  1. Точное совпадение типа (varchar(20), numeric(10,2))

  2. Совпадение базового типа (varchar, numeric)

  3. Поля с другими типами не сканируются.

I.3.8.1.6. data_sql_condition #

Назначение

Укажите пользовательские условия SQL WHERE для выборки данных вместо сканирования всей таблицы.

Схема

{
    "data_sql_condition": [
        {
            "schema": "<schema_name: string>",             # Check only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or check schemas matching regex pattern
            "table": "<table_name: string>",               # Check only this table
            "table_mask": "<table_regex_mask: string>",    # Or check tables matching regex pattern
            "sql_condition": # Condition in raw SQL format for filtering the data to scan
                """
                <raw_SQL_WHERE_condition: string>
                """
        }
    ]
}

Правила

  1. schema или schema_mask — обязательно

    • Вы должны указать либо schema, либо schema_mask

  2. table или table_mask — необязательно

    • Вы должны указать либо table, либо table_mask

  3. sql_condition — обязательно

    • Необходимо указать SQL-условие для раздела WHERE

    • Ключевое слово WHERE в sql_condition не требуется

Использование этого раздела

Пример мета-словаря

{
    "data_sql_condition": [
        {
            "schema": "public",
            "table": "salaries",
            "sql_condition": """
                WHERE hire_date >= '2024-01-01' and hire_date <= '2024-02-01'
            """
        }
    ]
}

Результат

Для сканирования данных таблицы public.salaries будут использоваться только данные за январь 2024 года.

I.3.8.1.7. data_func #

Назначение

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

Схема

{
    "data_func": {
        "<field_type: string>": [
            {
                "scan_func_per_field": "<scan_function_for_whole_field: string>",  
                "anon_func": "<anonymization_rule_template_for_field: string>", 
            },   
            {
                "scan_func": "<scan_function_for_field_per_row: string>",
                "anon_func": "<anonymization_rule_template_for_field: string>",
                "n_count": "<how_many_checks_must_be_passed: integer>",
            },
        ],
    }
}
КлючЗначение
field_typeТип PostgreSQL (или пользовательский тип). "anyelement" применяется ко всем типам.
scan_func_per_fieldPython-функция, вызываемая один раз для всего поля. Должна возвращать логическое значение.
scan_funcPython-функция, вызываемая для каждого значения поля. Должна возвращать логическое значение.
anon_funcШаблон правила анонимизации. Должен содержать заполнитель %s для имени поля.
n_countПоле считается чувствительным, если функция сканирования вернула True как минимум n раз для значений поля. Используется только для scan_func. (по умолчанию: 1)
I.3.8.1.8. Комбинации правил #
  1. scan_func или scan_func_per_field — обязательно

    • Вы должны указать либо scan_func, либо scan_func_per_field

    • Это определяет, где применяется правило.

Примечание

Функции для scan_func_per_field должны соответствовать этому шаблону:

CREATE OR REPLACE FUNCTION <schema>.<function_name>(
  schema_name TEXT,
  table_name TEXT,
  field_name TEXT
  field_type TEXT,
)
RETURNS boolean AS $$
BEGIN
  <function_logic>;
END;
$$ LANGUAGE plpgsql;

Функции для scan_func должны соответствовать этому шаблону:

CREATE OR REPLACE FUNCTION <schema>.<function_name>(
  value TEXT,
  schema_name TEXT,
  table_name TEXT,
  field_name TEXT
)
RETURNS boolean AS $$
BEGIN
  <function_logic>;
END;
$$ LANGUAGE plpgsql;

Использование этого раздела

Пример мета-словаря

{
    "data_func": {
        "anyelement": [
            {
                "scan_func_per_field": "custom_funcs.fulltext_search_by_organizations",
                "anon_func": "anon_funcs.digest(\"%s\", 'salt', 'md5')",
            },
            {
                "scan_func": "custom_funcs.is_employee_email",
                "anon_func": "anon_funcs.digest(\"%s\", 'salt', 'md5')",
                "n_count": 5
            }
        ]
    }
}

Приоритеты разрешения типа поля:

  1. Точное совпадение типа (varchar(20), numeric(10,2))

  2. Совпадение базового типа (varchar, numeric)

  3. anyelement

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Чувствительное Правило
public employees id Нет -
public employees full_name Нет -
public employees email Да custom_funcs.is_employee_email
public employees password Нет -
public employees phone Нет -
public employees hire_date Нет -
public salaries employee_id Нет -
public salaries monthly_salary Нет -
public salaries currency Нет -
ecommerce orders product_id Нет -
ecommerce orders client_name Нет -
ecommerce orders client_phone Нет -
ecommerce orders client_delivery_address Нет -
ecommerce orders count Нет -
ecommerce orders created Нет -
ecommerce orders status Нет -
I.3.8.1.9. data_const #

Назначение

Обнаружение конфиденциальных полей путем сопоставления полных или частичных констант.

Схема

{
    "data_const": {
        "constants": [
            "<field_value_full: string>",
        ],
        "partial_constants": [
            "<field_value_partial: string>",
        ]
    }
}
Ключ Значение
константы Нет Полное совпадение значения поля.
partial_constants Нет Совпадение подстроки в любом месте значения поля.

Примечание

Должен быть указан один из constants или partial_constants

Использование этого раздела

Пример мета-словаря

{
    "data_const": {
        "constants": [
            "done",
        ],
        "partial_constants": [
            "@example.com",
        ]
    }
}

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Чувствительное Правило
public employees id Нет -
public employees full_name Нет -
public employees email Да @example.com
public employees password Нет -
public employees phone Нет -
public employees hire_date Нет -
public salaries employee_id Нет -
public salaries monthly_salary Нет -
public salaries currency Нет -
ecommerce orders product_id Нет -
ecommerce orders client_name Нет -
ecommerce orders client_phone Нет -
ecommerce orders client_delivery_address Нет -
ecommerce orders count Нет -
ecommerce orders created Нет -
ecommerce orders status Да done
I.3.8.1.10. data_regex #

Назначение

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

Схема

{
    "data_regex": {
        "rules": [
            "<regex_rule: string>",
        ]
    }
}

Использование этого раздела

Пример мета-словаря

{
    "data_regex": {
        "rules": [
            """[A-Za-z0-9]+([._-][A-Za-z0-9]+)*@[A-Za-z0-9-]+(\.[A-Za-z]{2,})+""",  # email
            "^(7?\d{10})$",             # phone 7XXXXXXXXXX
        ]
    }
}

Пример структуры таблиц с соответствующими совпадениями в словаре

Схема Таблица Поле Чувствительное Правило
public employees id Нет -
public employees full_name Нет -
public employees email Да [A-Za-z0-9]+([._-][A-Za-z0-9]+)*@[A-Za-z0-9-]+(.[A-Za-z]{2,})+
public employees password Нет -
public employees phone Да ^(7?)$
public employees hire_date Нет -
public salaries employee_id Нет -
public salaries monthly_salary Нет -
public salaries currency Нет -
ecommerce orders product_id Нет -
ecommerce orders client_name Нет -
ecommerce orders client_phone Да ^(7?)$
ecommerce orders client_delivery_address Нет -
ecommerce orders count Нет -
ecommerce orders created Нет -
ecommerce orders status Нет -
I.3.8.1.11. funcs #

Назначение

Настройте функции анонимизации для каждого типа данных PostgreSQL.

Схема

{
    "funcs": {
        "<field_type: string>": "<anonymization_function_for_field_type: string>", 
        "default": "<universal_anonymization_function_for_all_field_types: string>"
    }
}

Использование этого раздела

Пример мета-словаря

{
    "funcs": {
        "text": "anon_funcs.digest(\"%s\", 'salt_word', 'md5')",
        "numeric(10,2)": "anon_funcs.noise(\"%s\", 10)",
        "numeric": "anon_funcs.noise(\"%s\", 30)",
        "varchar(10)": "anon_funcs.random_string(10)",
        "varchar(20)": "anon_funcs.random_string(20)",
        "varchar": "anon_funcs.digest(\"%s\", 'varchar_salt_word', 'sha256')",
        "timestamp": "anon_funcs.dnoise(\"%s\",  interval '6 month')",
        "default": "anon_funcs.digest(\"%s\", 'MySecretSaltWord', 'sha256')"
    }
}

Приоритеты разрешения типа поля:

  1. Точное совпадение типа (varchar(20), numeric(10,2))

  2. Совпадение базового типа (varchar, numeric)

  3. Функция из default

  4. Встроенная резервная функция: anon_funcs.digest("%s", 'salt_word', 'md5')

I.3.8.1.12. Общая схема мета-словаря #
{
    "skip_rules": [
        {
            "schema": "<schema_name: string>",             # Skip this schema from scanning
            "schema_mask": "<schema_regex_mask: string>",  # Or skip from scanning schemas matching regex pattern
            "table": "<table_name: string>",               # Skip from scanning only this table
            "table_mask": "<table_regex_mask: string>",    # Or skip from scanning tables matching regex pattern
            "fields": [  # Skip from scanning fields of tables
                "<field_name: string>"
            ]
        }
    ],
    "include_rules": [
        {
            "schema": "<schema_name: string>",             # Include only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or include schemas matching regex pattern
            "table": "<table_name: string>",               # Include only this table
            "table_mask": "<table_regex_mask: string>",    # Or include tables matching regex pattern
            "fields": [  # Include only this fields of tables for scanning
                "<field_name: string>"
            ]
        }
    ],
    "field": {
        "rules": [
            "<field_name_regex: string>",
        ],
        "constants": [
            "<field_name: string>",
        ]
    },
    "sens_pg_types": [
        "<field_type: string>",
    ],
    "data_sql_condition": [
        {
            "schema": "<schema_name: string>",             # Check only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or check schemas matching regex pattern
            "table": "<table_name: string>",               # Check only this table
            "table_mask": "<table_regex_mask: string>",    # Or check tables matching regex pattern
            "sql_condition": # Condition in raw SQL format for filtering the data to scan
                """
                <raw_SQL_WHERE_condition: string>
                """
        }
    ],
    "data_func": {  
        "<field_type: string>": [ 
            {
                "scan_func": "<scan_function_for_field: string>",  
                "anon_func": "<anonymization_rule_template_for_field: string>", 
                "n_count": "<how_many_checks_must_be_passed: integer>", 
            },
        ],
    },
    "data_const": {
        "constants": [
            "<field_value_full: string>",
        ],
        "partial_constants": [
            "<field_value_partial: string>",
        ]
    },
    "data_regex": {
        "rules": [
            "<regex_rule: string>",
        ]
    },
    "funcs": {
        "<field_type: string>": "<anonymization_function_for_field_type: string>", 
        "default": "<universal_anonymization_function_for_all_field_types: string>"
    }
}

I.3.8.2. Чувствительный словарь #

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

  1. Режим дампа

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

  2. Режим create-dict (сканирование)

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

  3. Режим View fields

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

  4. Режим View Data

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

Этот словарь можно создать вручную или сгенерировать автоматически с помощью режима create-dict (сканирование).

Примечание

Если поле присутствует как в словаре чувствительных данных, так и в словаре нечувствительных данных, приоритет имеет словарь чувствительных данных.

I.3.8.2.1. Схема #
{    
    "dictionary": [
        {
            "schema": "<schema_name: string>",
            "table": "<table_name: string>",
            "fields": {
                "<field_name: string>": "<anonymization_rule_for_field: string>",
            },
            "sql_condition": # Optional. Condition in raw SQL format for filtering the data to dump. (This section ignored for create-dict (scan) mode
                """
                <raw_SQL_WHERE_condition: string>
                """
        }
    ],
    # Optional section. It is used to exclude schemas and tables from the data dump.  
    "dictionary_exclude": [
        {
            "schema": "<schema_name: string>",             # Exclude only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or exclude schemas matching regex pattern
            "table": "<table_name: string>",               # Exclude only this table
            "table_mask": "<table_regex_mask: string>",    # Or exclude tables matching regex pattern
        }
    ]
}

Примечание

sql_condition в разделе dictionary является необязательным. Его можно использовать для выборки части данных. Пример: получение данных таблицы только за последнюю неделю.

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

  • В dictionary_exclude вы должны использовать либо schema, либо schema_mask → не оба одновременно.

  • В dictionary_exclude вы должны использовать либо table, либо table_mask → но не оба одновременно.

I.3.8.2.2. Использование словаря #

Пример структуры базы данных

Схема Таблица Поле
public employees id
public employees full_name
public employees email
public employees hire_date
public salaries employee_id
public salaries monthly_salary
public salaries currency
ecommerce orders product_id
ecommerce orders count
ecommerce orders client_name
ecommerce orders delivery_address
ecommerce orders created
ecommerce orders status
tenant_a projects title
tenant_a projects description
tenant_b projects title
tenant_b projects description
tenant_c projects title
tenant_c projects description

Пример чувствительного словаря

{    
    "dictionary": [
        {
            "schema": "public",
            "table": "employees",
            "fields": {
                "full_name": "anon_funcs.digest(\"full_name\", 'salt_word', 'sha256')",  # hashing employees names 
                "email": "md5(\"email\") || @abc.com",  # hashing employee emails while preserving email format
            },
        },
        {
            "schema": "public",
            "table": "salaries",
            "fields": {
                "monthly_salary": "10000",  # just defines one value for the field for all rows
            },
        },
        {
            "schema": "ecommerce",
            "table": "orders",
            "fields": {
                "client_name": "anon_funcs.digest(\"client_name\", 'salt_word', 'sha256')",
                "delivery_address": "anon_funcs.digest(\"delivery_address\", 'salt_word', 'sha256')",
            },
            "sql_condition":  # Dumping only the orders completed within the last week
                """
                WHERE created > NOW() - '7 days'::interval
                AND status = 'done'
                """
        }
    ],
    # Excluding all tables from schemas `tenant_a`, `tenant_b`, `tenant_c` 
    "dictionary_exclude": [
        {
            "schema_mask": "tenant_.*",
            "table_mask": "*",
        }
    ]
}

Этот словарь соответствует следующим полям таблицы:

Схема Таблица Поле Используется в режиме dump Используется в режиме create-dict (сканирование)
public employees id Выгружено как есть Поля сканируются с использованием правил мета-словаря
public employees full_name Выгружено с анонимизацией Исключено из проверок на чувствительность как чувствительное поле
public employees email Выгружено с анонимизацией Исключено из проверок на чувствительность как чувствительное поле
public employees hire_date Выгружено как есть Поля сканируются с использованием правил мета-словаря
public salaries employee_id Выгружено как есть Поля сканируются с использованием правил мета-словаря
public salaries monthly_salary Выгружено с анонимизацией Исключено из проверок на чувствительность как чувствительное поле
public salaries currency Выгружено как есть Поля сканируются с использованием правил мета-словаря
ecommerce orders product_id Выгружено как есть Поля сканируются с использованием правил мета-словаря
ecommerce orders client_name Выгружено с анонимизацией Исключено из проверок на чувствительность как чувствительное поле
ecommerce orders delivery_address Выгружено с анонимизацией Исключено из проверок на чувствительность как чувствительное поле
ecommerce orders count Выгружено как есть Поля сканируются с использованием правил мета-словаря
ecommerce orders created Выгружено как есть Поля сканируются с использованием правил мета-словаря
ecommerce orders status Выгружено как есть Поля сканируются с использованием правил мета-словаря

I.3.8.3. Нечувствительный словарь #

Нечувствительный словарь используется только во время режима create-dict (сканирование) для ускорения обработки. Он определяет, какие поля должны рассматриваться как не содержащие чувствительных данных. Поля, перечисленные здесь, исключаются из всех проверок на чувствительность в соответствии с правилами мета-словаря.

Этот словарь можно создать вручную или сгенерировать автоматически с помощью режима create-dict (сканирование) с опцией --output-no-sens-dict-file.

Примечание

Если поле присутствует как в словаре чувствительных данных, так и в словаре нечувствительных данных, приоритет имеет словарь чувствительных данных.

I.3.8.3.1. Схема #
{    
    "no_sens_dictionary": [
        {
            "schema": "<schema_name: string>",
            "table": "<table_name: string>",
            "fields": [
                "<field_name: string>",
            ]
        },
    ]
}
I.3.8.3.2. Использование словаря #

Пример структуры таблиц

Схема Таблица Поле
public employees id
public employees full_name
public employees email
public employees hire_date
public salaries employee_id
public salaries monthly_salary
public salaries currency

Пример нечувствительного словаря

{
    "no_sens_dictionary": [
        {
            "schema": "public",
            "table": "employees",
            "fields": [
                "id",
                "hire_date",
            ]
        },
        {
            "schema": "public",
            "table": "salaries",
            "fields": [
                "employee_id",
                "currency",
            ]
        },
    ]
}

Этот словарь соответствует следующим полям таблицы:

Схема Таблица Поле Используется в режиме create-dict (сканирование)
public employees id Исключено из проверок чувствительности как поле нечувствительное
public employees full_name Поля, сканируемые с использованием правил мета-словаря
public employees email Поля, сканируемые с использованием правил мета-словаря
public employees hire_date Исключено из проверок на чувствительность как поле нечувствительное
public salaries employee_id Исключено из проверок на чувствительность как поле нечувствительное
public salaries monthly_salary Поля, просканированные с использованием правил мета-словаря
public salaries currency Исключено из проверок на чувствительность как поле нечувствительное

I.3.8.4. Словарь таблиц #

Словарь tables определяет, какие таблицы участвуют в операциях частичного дампа и частичного восстановления. Он может выступать либо в роли белого списка (включать только указанные), либо в роли черного списка (исключать только указанные).

Используйте этот словарь, когда вам нужно:

  • выгрузить или восстановить только определённые таблицы

  • исключить нежелательные таблицы из дампа или восстановления

I.3.8.4.1. Схема #
{
    "tables": [
        {
            "schema": "<schema_name: string>",             # Include only this schema
            "schema_mask": "<schema_regex_mask: string>",  # Or include schemas matching regex pattern
            "table": "<table_name: string>",               # Include only this table
            "table_mask": "<table_regex_mask: string>",    # Or include tables matching regex pattern
        }
    ]
}

Примечание

  • Вы должны использовать либо schema, либо schema_mask → не оба одновременно.

  • Вы должны использовать либо table, либо table_mask — но не оба одновременно.

I.3.8.4.2. Использование словаря #

Вы можете использовать один и тот же словарь в двух разных ролях:

  • Белый список — выгружать/восстанавливать только совпадающие таблицы

  • Черный список — выгрузить/восстановить все таблицы, кроме совпадающих

Пример структуры базы данных

Схема Таблица
public employees
public departments
public positions
public salaries
public users
ecommerce products
ecommerce categories
ecommerce orders
ecommerce order_items
tenant_a users
tenant_a projects
tenant_a tasks
tenant_a comments
tenant_b users
tenant_b projects
tenant_b tasks
tenant_b comments
tenant_c users
tenant_c projects
tenant_c tasks
tenant_c comments

Пример словаря таблиц

{
    "tables": [  
        {
            "schema": "public",
            "table": "employees"
        },
        {
            "schema": "ecommerce",
            "table_mask": "^orders"
        },
        {
            "schema_mask": "_a$",
            "table": "projects"
        },
        {
            "schema_mask": "*",
            "table_mask": "users"
        },
    ]
}

Этот словарь соответствует следующим таблицам:

Схема Таблица Соответствует правилу
ecommerce orders schema="ecommerce", table_mask="^orders"
ecommerce order_items schema="ecommerce", table_mask="^orders"
tenant_a projects schema_mask="_a$", table="projects"
tenant_a users schema_mask="*", table_mask="users"
tenant_b users schema_mask="*", table_mask="users"
tenant_c users schema_mask="*", table_mask="users"
public users schema_mask="*", table_mask="users"
public employees schema="public", таблица="employees"

I.3.9. Этапы отладки процесса анонимизации #

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

Каждый этап имитирует определённую часть процесса анонимизации:

  • Этап 1 — Проверка словаря

    Проверяет конфиденциальный словарь и проверяет логику SQL без экспорта каких-либо данных.

  • Этап 2 — Проверка данных

    Выполняет проверки анонимизации на реальных данных с ограниченной выборкой (LIMIT 100) с использованием подготовленной схемы базы данных.

  • Этап 3 — Полная проверка

    Выполняет полную логику анонимизации с выборкой данных (LIMIT 100), но без необходимости подготовки базы данных.

Эти этапы помогают быстро отлаживать правила, функции анонимизации, SQL-условия и конфигурацию словаря перед запуском полного процесса анонимизированного дампа/восстановления.

I.3.9.1. Этап 1: Проверка словаря #

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

Диаграмма I.3. dbg-stage-1.png

dbg-stage-1.png

   python pg_anon.py dump \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_source_db \
                     --output-dir=test_dbg_stages \
                     --prepared-sens-dict-file=test_dbg_stages.py \
                     --clear-output-dir \
                     --verbose=debug \
                     --debug \
                     --dbg-stage-1-validate-dict

I.3.9.2. Этап 2: Проверка данных #

Проверка данных, отображение таблиц и выполнение SQL-запросов с возможностью экспорта данных и ограничением 100 в подготовленной базе данных. На этом этапе требуется база данных со всей структурой только в состоянии pre-data, которое описано в –prepared-sens-dict-file.

  • Если вы хотите создать базу данных с необходимой структурой, просто выполните:

Однократный дамп структуры:

   python pg_anon.py sync-struct-dump \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_source_db \
                     --output-dir=test_stage_2 \
                     --prepared-sens-dict-file=test_dbg_stages.py \
                     --clear-output-dir \
                     --verbose=debug \
                     --debug \
                     --dbg-stage-3-validate-full

И повторить столько раз, сколько будете воспроизводить структуру:

   su - postgres -c "psql -U postgres -d postgres -c \"DROP DATABASE IF EXISTS test_target_db_7\""
   su - postgres -c "psql -U postgres -d postgres -c \"CREATE DATABASE test_target_db_7\""
   python pg_anon.py sync-struct-restore \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_target_db_7 \
                     --input-dir=test_stage_2 \
                     --verbose=debug \
                     --debug 
  • Проверка данных на этапе дампа:

Диаграмма I.4. dbg-stage-2.png

dbg-stage-2.png

   python pg_anon.py dump \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_source_db \
                     --output-dir=test_dbg_stages \
                     --prepared-sens-dict-file=test_dbg_stages.py \
                     --clear-output-dir \
                     --verbose=debug \
                     --debug \
                     --dbg-stage-2-validate-data
  • Проверка данных на этапе воспроизведения данных:

   python pg_anon.py sync-data-restore \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_target_db_7 \
                     --input-dir=test_dbg_stages \
                     --verbose=debug \
                     --debug 
   
   # And for example view all data in every table:
   su - postgres -c "psql -U postgres -d test_target_db_7 -c \"SELECT * FROM public.contracts\""

I.3.9.3. Этап 3: Полная проверка #

Диаграмма I.5. dbg-stage-3.png

dbg-stage-3.png

Выполняется вся логика анонимизации с limit 100 в SQL-запросах. На этом этапе вам не нужна подготовленная база данных, просто выполните:

   su - postgres -c "psql -U postgres -d postgres -c \"DROP DATABASE IF EXISTS test_target_db_8\""
   su - postgres -c "psql -U postgres -d postgres -c \"CREATE DATABASE test_target_db_8\""
  • Этап полной проверки при дампе:

   python pg_anon.py dump \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_source_db \
                     --output-dir=test_dbg_stages \
                     --prepared-sens-dict-file=test_dbg_stages.py \
                     --clear-output-dir \
                     --verbose=debug \
                     --debug \
                     --dbg-stage-3-validate-full
  • Этап полной проверки при воспроизведении:

   python pg_anon.py restore \
                     --db-host=127.0.0.1 \
                     --db-user=postgres \
                     --db-user-password=postgres \
                     --db-name=test_target_db_8 \
                     --input-dir=test_dbg_stages \
                     --verbose=debug \
                     --debug 
   
   # And for example view all data in every table:
   su - postgres -c "psql -U postgres -d test_target_db_8 -c \"SELECT * FROM public.contracts\""

I.3.10. FAQ #

I.3.10.1. Где я могу найти журналы операций и параметры запуска? #

Все данные о запуске хранятся в каталоге /path_to_pg_anon/runs. Внутри следующая структура: <year>/<month>/<day>/<operation_id>.

Каждый каталог операции содержит:

  • каталог logs со всеми файлами журналов

  • файл run_options.json со всеми параметрами, использованными для запуска pg_anon

Если была использована опция --save-dicts, также появятся каталоги input и output. Они содержат все входные и выходные словари для этого запуска.

I.3.10.2. Могу ли я восстановить дамп pg_anon с помощью pg_dump? #

Нет. Формат дампа pg_anon не совместим с pg_dump из-за особенностей анонимизации.

По той же причине обычная резервная копия, созданная с помощью pg_dump, не может быть восстановлена с использованием pg_anon.

I.3.10.3. Изменяет ли pg_anon структуру или данные исходной базы данных во время выполнения scan, dump, view-data или view-fields? #

pg_anon не изменяет ни структуру, ни данные исходной базы данных.

Единственное, что добавляет pg_anon, — это схема anon_funcs, которая необходима для его внутренних операций.

I.3.10.4. Могу ли я использовать пользовательские функции для сканирования? #

Да. Мета-словарь содержит раздел data_func. В этом разделе вы можете использовать любую пользовательскую SQL-функцию для проверки чувствительности.

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

Такие функции должны соответствовать этому шаблону:

CREATE OR REPLACE FUNCTION <schema>.<function_name>(
  value TEXT,
  schema_name TEXT,
  table_name TEXT,
  field_name TEXT
)
RETURNS boolean AS $$
BEGIN
  <function_logic>;
END;
$$ LANGUAGE plpgsql;

I.3.10.5. Могу ли я использовать пользовательские функции для анонимизации? #

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

Вы должны убедиться, что анонимизированные значения соответствуют формату поля. Например, если тип поля — varchar(15), вы должны вручную убедиться, что сгенерированное значение не превышает 15 символов.

Если формат нарушен, дамп может быть успешно создан, но восстановление может завершиться неудачей.

Также для этих случаев может быть использован раздел data_func с использованием scan_func для сравнения длины поля и определённой anon_function для конкретной длины.

Например, функция сканирования ниже получает только поля длиной менее 20 символов и содержащие электронные адреса:

CREATE OR REPLACE FUNCTION my_scan_funcs.is_email_field_with_len_20_chars(
  value TEXT,
  schema_name TEXT,
  table_name TEXT,
  field_name TEXT
)
RETURNS boolean AS $$
DECLARE
    max_len integer;
    is_email boolean;
BEGIN
    SELECT c.character_maximum_length
    INTO max_len
    FROM information_schema.columns c
    WHERE c.table_schema = $2
      AND c.table_name = $3
      AND c.column_name = $4;

    -- field length must be 20 characters
    if max_len != 20 then
        return false;
    end if;  	
   
   -- value must be not null for comparison
    if $1 is null then
    	return false;
    end if;  	
   
    -- check email format by regexp
    return $1 ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';
END;
$$ LANGUAGE plpgsql;

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

{
    "data_func": {
        "varchar": [
            {
                "scan_func": "my_scan_funcs.is_email_field_with_len_20_chars",
                "anon_func": "lower(anon_funcs.random_string(9)) || '@secret.com'",
                "n_count": 10
            }
        ]
    }
}

I.3.10.6. Является ли этап сканирования обязательным? #

Нет. Вы можете создать все необходимые словари вручную или использовать ранее созданные словари.

I.3.10.7. Зачем загружать чувствительные и нечувствительные словари во время сканирования? #

Они используются только для ускорения сканирования.

Эти словари действуют как кэш, позволяя pg_anon сразу определять, какие поля являются конфиденциальными, а какие — нет.

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

Если появляются новые поля, которые отсутствуют в словарях, pg_anon будет обрабатывать их с использованием правил из мета-словаря.

I.3.10.8. Когда следует использовать --config с файлом конфигурации? #

Если вы планируете использовать pg_anon с разными основными выпусками Tantor BE, вам следует определить файл конфигурации.

Это гораздо проще настроить один раз, чем каждый раз передавать пути в pg_dump и pg_restore.

Если вы всегда используете одну версию Tantor BE, будут использоваться системные pg_dump и pg_restore, и файл конфигурации не требуется.

I.3.10.9. Могу ли я разделить один большой словарь на несколько небольших? #

Да. Все параметры, связанные со словарями, принимают списки файлов.

При запуске pg_anon объединяет их во внутренний единый словарь.

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

I.3.10.10. Ошибка восстановления: База данных не пуста #

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

Это делается для предотвращения случайной потери данных в целевой базе данных.

При необходимости используйте опции --drop-db или --clean-db во время восстановления.

I.3.10.11. Ошибка восстановления: К базе данных обращаются другие пользователи #

При использовании опции --drop-db целевая база данных будет пересоздана с помощью DROP DATABASE и CREATE DATABASE.

Если существуют активные подключения, команда DROP DATABASE не может быть выполнена.

Вы должны завершить все активные сессии и повторно выполнить операцию восстановления.

I.3.10.12. Различие между опциями --drop-db и --clean-db в режиме восстановления #

  • --drop-db — пересоздать целевую базу данных с помощью команд DROP DATABASE и CREATE DATABASE. После этого выполнить процесс восстановления на пустой базе данных.

  • --clean-db — выполняет восстановление, аналогичное pg_restore –clean –if-exists. Создаёт отсутствующие таблицы из резервной копии в целевой базе данных. Также сохраняет дополнительные таблицы, которые существуют в целевой БД и не содержатся в восстанавливаемой резервной копии. Эта опция не требует пустой целевой базы данных.

I.3.10.13. Определение оптимального количества процессов и подключений #

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

  • max_connections — максимальное количество подключений, разрешённых вашей базой данных Tantor BE

  • Количество ядер CPU

  • Зарезервированные подключения (обычно 3-10 для обслуживания/административных подключений)

Важные замечания:

  • Превышение max_connections может привести к сбоям pg_anon и повлиять на другие приложения базы данных

  • Обеспечьте достаточный запас подключений для других сервисов

I.3.10.13.2. Пример вычисления #
  • Ядра CPU: 4

  • max_connections: 100

  • reserved_connections: 5

  • --processes: 4

  • –db-connections-per-process: (100 - 5) / 4 ≈ 23,75 → 23

  • Проверка: 4 процесса × 23 соединения = 92 всего соединения (в пределах лимита 100)

I.3.11. Библиотека SQL-функций #

Все функции содержатся в файле init.sql. После запуска pg_anon в режиме init они будут находиться в схеме anon_funcs в исходной базе данных. Если вы хотите написать новую функцию, просто создайте её в схеме anon_funcs в вашей исходной базе данных.

Список некоторых функций, которые можно использовать в словарях:

I.3.11.1. Список функций #

I.3.11.1.1. noise #

Добавить случайное число к вещественному числу:

SELECT anon_funcs.noise(100, 1.2);
>> 123
I.3.11.1.2. dnoise #

Добавить случайное число к дате или временной метке:

SELECT anon_funcs.dnoise('2020-02-02 10:10:10'::timestamp, interval '1 month');
>> 2020-03-02 10:10:10
I.3.11.1.3. digest #

хешировать строковое значение с указанной хеш-функцией:

SELECT anon_funcs.digest('text', 'salt', 'sha256');
>> '3353e....'
I.3.11.1.4. partial #

Оставить первые несколько символов (2-й аргумент) и последние несколько символов (4-й аргумент) указанной строки, добавив константу (3-й аргумент) между ними:

SELECT anon_funcs.partial('123456789', 1, '***', 3);
>> 1***789
I.3.11.1.5. partial_email #

Замаскировать адрес электронной почты:

SELECT anon_funcs.partial_email('example@gmail.com');
>> ex*****@gm*****.com
I.3.11.1.6. random_string #

Сгенерировать случайную строку указанной длины:

SELECT anon_funcs.random_string(7);
>> H3ZVL5P
I.3.11.1.7. random_zip #

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

SELECT anon_funcs.random_zip();
>> 851467
I.3.11.1.8. random_date_between #

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

SELECT anon_funcs.random_date_between(
   '2020-02-02 10:10:10'::timestamp,
   '2022-02-05 10:10:10'::timestamp
);
>> 2021-11-08 06:47:48.057
I.3.11.1.9. random_date #

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

SELECT anon_funcs.random_date();
>> 1911-04-18 21:54:13.139
I.3.11.1.10. random_int_between #

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

SELECT anon_funcs.random_int_between(100, 200);
>> 159
I.3.11.1.11. random_bigint_between #

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

SELECT anon_funcs.random_bigint_between(6000000000, 7000000000);
>> 6268278565
I.3.11.1.12. random_phone #

Сгенерировать случайный номер телефона:

SELECT anon_funcs.random_phone('+7');
>> +7297479867
I.3.11.1.13. random_hash #

Сгенерировать случайный хеш, используя указанную функцию:

SELECT anon_funcs.random_hash('seed', 'sha512');
>> b972f895ebea9cf2f65e19abc151b8031926c4a332471dc5c40fab608950870d6dbddcd18c7e467563f9b527e63d4d13870e4961c0ff2a62f021827654ae51fd
I.3.11.1.14. random_in #

Выбрать случайный элемент из массива:

SELECT anon_funcs.random_in(array['a', 'b', 'c']);
>> a
I.3.11.1.15. hex_to_int #

Преобразовать шестнадцатеричное значение в десятичное:

SELECT anon_funcs.hex_to_int('8AB');
>> 2219

I.3.11.2. pgcrypto #

В дополнение к существующим функциям в схеме anon_funcs, могут также использоваться функции из расширения pgcrypto.

CREATE EXTENSION IF NOT EXISTS pgcrypto;

Пример использования шифрования с кодированием base64 для хранения зашифрованного значения в текстовом поле:

SELECT encode((SELECT encrypt('data', 'password', 'bf')), 'base64');
>> cSMq9gb1vOw=

SELECT decrypt(
(
SELECT decode('cSMq9gb1vOw=', 'base64')
), 'password', 'bf');
>> data

I.3.11.3. Как добавить собственные функции #

Кроме того, добавление новых функций анонимизации можно выполнить, добавив init.sql в файл, а затем запустив pg_anon в режиме init.

I.3.12. API #

I.3.12.1. Методы API для основных операций #

I.3.12.1.1. Проверка подключения к базе данных #

POST /api/stateless/check_db_connection

Описание

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

Если соединение прошло успешно, конечная точка возвращает код состояния 200.

Проверьте схему тела запроса на подключение к БД

Поле Тип Обязательное Описание
host строка Да Хост базы данных.
port целое число Да Порт базы данных.
db_name строка Да Имя базы данных.
user_login строка Да Имя пользователя базы данных.
user_password строка Да Пароль пользователя базы данных.

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/check_db_connection \
-H "Content-Type: application/json" \
-d '{
  "host": "localhost",
  "port": "5432",
  "db_name":  "source_db",
  "user_login": "postgres",
  "user_password":  "postgres"
}'

Ответы

Код состояния Описание Компонент
200 База данных доступна -
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError
I.3.12.1.2. Выполнение create-dict (сканирование) #

POST /api/stateless/scan

Описание

Запускает pg_anon в режиме create-dict (сканирование) в фоне.

Жизненный цикл операции:

  1. Клиент вызывает эту конечную точку.

  2. API возвращает один из следующих кодов статуса:

    • 200 — операция сканирования была успешно запущена.

    • 400 или 422 — некорректный запрос; операция не начата.

  3. Сервис отправляет вебхук-запрос со статусом in_progress на webhook_status_url. Формат полезной нагрузки описан в схеме вебхук-запроса сканирования

  4. Операция выполняется в фоновом режиме.

  5. Если во время обработки происходит ошибка, сервис отправляет вебхук-запрос со статусом error.

  6. Если операция завершается успешно, служба отправляет вебхук-запрос со статусом success.

Схема запроса сканирования

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Принимает любую строку. Возвращается без изменений в запросах webhook.
db_connection_params DbConnectionParams Да Учетные данные для подключения к исходной базе данных.
webhook_status_url строка Да URL обратного вызова, который принимает POST-запросы в формате, описанном в схеме вебхук-запроса сканирования.
webhook_metadata любой Нет Произвольные метаданные. Отправляются без изменений в запросах webhook.
webhook_extra_headers JSON Нет Дополнительные HTTP-заголовки, добавляемые к запросам webhook. Полезно для интеграции, например, чтобы включить заголовок Authorization.
webhook_verify_ssl boolean Нет Включает или отключает проверку SSL-сертификата для запросов webhook.
save_dicts boolean Нет Сохраняет все входные и выходные словари в каталог runs. Полезно для отладки или интеграции. По умолчанию: false.
type строка Нет Определяет режим сканирования: full или partial. По умолчанию: partial.
depth целое число Нет Максимальное количество строк таблицы, используемых для частичного сканирования. Применяется только если type = partial. По умолчанию: 10000.
meta_dict_contents массив DictionaryContent Да Содержимое мета-словаря, определяющее правила сканирования полей.
sens_dict_contents массив DictionaryContent Нет Содержимое чувствительного словаря. Используется для повышения производительности сканирования.
no_sens_dict_contents массив DictionaryContent Нет Содержимое нечувствительного словаря. Используется для повышения производительности сканирования.
need_no_sens_dict boolean Нет Если true, генерирует нечувствительный словарь и возвращает его в поле no_sens_dict_contents полезной нагрузки webhook.
proc_count целое число Нет Количество процессов, используемых для многопроцессорной обработки. По умолчанию: 4.
proc_conn_count целое число Нет Количество подключений к базе данных, выделяемых на каждый процесс для операций ввода-вывода. По умолчанию: 4.

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/scan \
-H "Content-Type: application/json" \
-d '{
  "operation_id": "my-uniq-scan-id-0001",
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "webhook_status_url": "https://my-service/pg-anon-result-processor",
  "webhook_metadata": {"extra_field_1": "extra_data", "extra_field_2": {"fld1": [1,2,3], "fld2": 123}},
  "webhook_extra_headers": {"Authorization": "Api-key my_super_secret_api_key", "X-my-service-extra-header": "header value"},
  "webhook_verify_ssl": true,
  "save_dicts": true,
  "type": "partial",
  "depth": 10000,
  "meta_dict_contents": [{
    "name": "my simple meta dict with email scan rule",
    "content": "{\"data_regex\": {\"rules\": [\".*@.*\"]}, \"funcs\": {\"text\": \"md5(%s)\"}}"
  }],
  "sens_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "no_sens_dict_contents": [{
    "name": "non-sens dict example",
    "content": "{\"no_sens_dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": [\"id\", \"created\"]}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": [\"id\", \"registered\"]}]}"
  }],
  "need_no_sens_dict": true,
  "proc_count": 4,
  "proc_conn_count": 4
}'

Схема вебхук-запроса сканирования

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Копируется из operation_id исходного запроса сканирования.
internal_operation_id строка Нет Внутренний идентификатор операции pg_anon, генерируемый автоматически. Присутствует только когда status имеет значение success или error. Может использоваться для сопоставления события webhook с данными операции и журналами, хранящимися в каталоге /runs. Также используется в конечных точках Operation.
status_id целое число Да Числовой код статуса. Возможные значения: 2 — успех, 3 — ошибка, 4 — выполняется.
status строка Да Удобочитаемый статус. Возможные значения: success, error, in_progress.
webhook_metadata любой Нет Метаданные, передаются «как есть». Копируются из поля webhook_metadata запроса сканирования.
started строка Нет Временная метка начала операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
ended строка Нет Временная метка окончания операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
error строка Нет Сообщение об ошибке. Присутствует только если status = error.
error_codeстрокаНетМашиночитаемый код ошибки для сопоставления i18n. Присутствует только если status = error.
run_options JSON Нет Снимок параметров выполнения операции. Полезно для анализа, отладки и повторного запуска операции. Присутствует только когда status = success или error.
sens_dict_content DictionaryContent Нет Полученный чувствительный словарь. Возвращается только при успешном завершении сканирования. Используется для операций дампа или повторных сканирований.
no_sens_dict_content DictionaryContent Нет Полученный нечувствительный словарь. Присутствует только если сканирование завершилось успешно и исходный запрос содержал need_no_sens_dict = true.

Ответы

Код состояния Описание Компонент
201 Операция успешно запущена -
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError
I.3.12.1.3. Отображение полей базы данных с правилами анонимизации #

POST /api/stateless/view-fields

Описание

Запускает pg_anon в режиме View Fields и возвращает результат в ответе.

View-fields request body schema

Поле Тип Обязательное Описание
db_connection_params DbConnectionParams Да Учетные данные исходной базы данных.
sens_dict_contents массив DictionaryContent Нет Содержимое конфиденциального словаря, которое определяет правила для конфиденциальных полей.
schema_name строка Нет Фильтрация по имени схемы.
schema_mask строка Нет Фильтровать по имени схемы с использованием регулярного выражения.
table_name строка Нет Фильтровать по имени таблицы.
table_mask строка Нет Фильтровать по имени таблицы с использованием регулярного выражения.
view_only_sensitive_fields boolean Нет Отображает только конфиденциальные поля (по умолчанию: все поля).
fields_limit_count целое число Нет Максимальное количество полей для вывода (по умолчанию: 5000).

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/view-fields \
-H "Content-Type: application/json" \
-d '{
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "sens_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "schema_name": "public",
  "table_mask": "^client",
  "view_only_sensitive_fields": true,
  "fields_limit_count": 1000
}'

Ответы

Код состояния Описание Компонент
200 Успешный ответ ViewFieldsResponse
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError
I.3.12.1.4. Отображение таблицы с анонимизированными данными #

POST /api/stateless/view-data

Описание

Отображает данные таблицы в исходном и анонимизированном вариантах для сравнения. Запускает pg_anon в режиме View Data и возвращает результат в ответе.

View-data request body schema

Поле Тип Обязательное Описание
db_connection_params DbConnectionParams Да Учетные данные исходной базы данных.
sens_dict_contents массив DictionaryContent Нет Содержимое чувствительного словаря, определяющее правила для чувствительных полей.
schema_name строка Да Имя схемы.
table_name строка Да Имя таблицы.
limit целое число Нет Количество отображаемых строк (по умолчанию: 100).
offset целое число Нет Смещение строки для постраничного вывода (по умолчанию: 0).

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/view-data \
-H "Content-Type: application/json" \
-d '{
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "sens_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "schema_name": "public",
  "table_name": "clients",
  "limit": 10,
  "offset": 20
}'

Ответы

Код состояния Описание Компонент
200 Успешный ответ ViewDataResponse
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError
I.3.12.1.5. Отображение только схем базы данных для предварительного просмотра #
POST /api/stateless/preview

Описание

Возвращает список схем базы данных. Может быть отфильтрован по подстроке имени схемы.

Схема тела запроса для предварительного просмотра схем

ПолеТипОбязательноеОписание
db_connection_paramsDbConnectionParamsДаУчетные данные исходной базы данных.
schema_filterстрокаНетФильтр схемы по подстроке имени (с учетом регистра).

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/preview \
-H "Content-Type: application/json" \
-d '{
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "schema_filter": "public"
}'

Ответы

Код состоянияОписаниеКомпонент
200Успешный ответPreviewSchemasResponse
400Неверный запросErrorResponse
500Внутренняя ошибка сервераErrorResponse
422Ошибка проверкиHTTPValidationError
I.3.12.1.6. Отображение таблицы базы данных с полями для предварительного просмотра #
POST /api/stateless/preview/{schema}

Описание

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

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

ПолеТипОбязательныйОписание
db_connection_paramsDbConnectionParamsДаУчетные данные исходной базы данных.
sens_dict_contentsмассив содержимого словаряДаСодержимое чувствительного словаря, определяющее правила для чувствительных полей.
лимитцелое числоНетМаксимальное количество возвращаемых таблиц (по умолчанию: 20).
смещениецелое числоНетКоличество таблиц, которые нужно пропустить для постраничного вывода (по умолчанию: 0).
table_filterстрокаНетФильтр таблицы по подстроке имени (с учетом регистра).
view_only_sensitive_tablesbooleanНетЕсли true, возвращает только те таблицы, которые соответствуют словарю чувствительных данных (по умолчанию: false).

Параметры пути

ПолеТипОбязательныйОписание
схемастрокаДаИмя схемы

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/preview/public \
-H "Content-Type: application/json" \
-d '{
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "sens_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "limit": 20,
  "offset": 0,
  "table_filter": "user",
  "view_only_sensitive_tables": false
}'

Ответы

Код состоянияОписаниеКомпонент
200Успешный ответPreviewSchemaTablesResponse
400Неверный запросОтвет с ошибкой
500Внутренняя ошибка сервераErrorResponse
422Ошибка проверкиHTTPОшибкаПроверки
I.3.12.1.7. Выполнение дампа #

POST /api/stateless/dump

Описание

Запускает pg_anon в режиме Dump в фоне.

Жизненный цикл операции:

  1. Клиент вызывает эту конечную точку.

  2. API возвращает один из следующих кодов статуса:

    • 200 — операция дампа была успешно запущена.

    • 400 или 422 — некорректный запрос; операция не начата.

  3. Сервис отправляет вебхук-запрос со статусом in_progress на webhook_status_url. Формат полезной нагрузки описан в схеме запроса webhook дампа.

  4. Операция выполняется в фоновом режиме.

  5. Если во время обработки происходит ошибка, сервис отправляет вебхук-запрос со статусом error.

  6. Если операция завершается успешно, служба отправляет вебхук-запрос со статусом success.

Схема запроса дампа

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Принимает любую строку. Возвращается без изменений в запросах webhook.
db_connection_params DbConnectionParams Да Учетные данные для подключения к исходной базе данных.
webhook_status_url строка Да URL обратного вызова, который принимает POST-запросы в формате, описанном в схеме вебхук-запроса дампа.
webhook_metadata любой Нет Произвольные метаданные. Отправляются без изменений в запросах webhook.
webhook_extra_headers JSON Нет Дополнительные HTTP-заголовки, добавляемые к запросам webhook. Полезно для интеграции, например, чтобы включить заголовок Authorization.
webhook_verify_ssl boolean Нет Включает или отключает проверку SSL-сертификата для запросов webhook.
save_dicts boolean Нет Сохраняет все входные и выходные словари в каталог runs. Полезно для отладки или интеграции. По умолчанию: false.
тип строка Нет Определяет тип дампа. Варианты: dump, sync-struct-dump, sync-data-dump. По умолчанию: dump.
sens_dict_contents массив DictionaryContent Да Содержимое чувствительного словаря, определяющее правила анонимизации данных во время дампа.
partial_tables_dict_contents массив DictionaryContent Нет Содержимое словаря таблиц, указывающее таблицы, которые необходимо включить в частичную дамп-копию.
partial_tables_exclude_dict_contents массив DictionaryContent Нет Содержимое словаря таблиц, указывающее таблицы, которые нужно исключить из частичной дампы.
output_path строка Нет Путь, по которому будет создан дамп внутри /path_to_pg_anon/output. Например, "my_dump" будет находиться по адресу /path_to_pg_anon/output/my_dump.
pg_dump_path строка Нет Путь к инструменту Postgres pg_dump. По умолчанию: /usr/bin/pg_dump.
pg_dump_optionsстрокаНетДополнительные параметры, передаваемые непосредственно утилите pg_dump. Пример: "--no-comments --encoding=LATIN1".
ignore_privileges boolean Нет Игнорировать привилегии из исходной базы данных.
proc_count целое число Нет Количество процессов, используемых для многопроцессорной обработки. По умолчанию: 4.
proc_conn_count целое число Нет Количество подключений к базе данных, выделяемых на каждый процесс для операций ввода-вывода. По умолчанию: 4.

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/dump \
-H "Content-Type: application/json" \
-d '{
  "operation_id": "my-uniq-scan-id-0001",
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "webhook_status_url": "https://my-service/pg-anon-result-processor",
  "webhook_metadata": {"extra_field_1": "extra_data", "extra_field_2": {"fld1": [1,2,3], "fld2": 123}},
  "webhook_extra_headers": {"Authorization": "Api-key my_super_secret_api_key", "X-my-service-extra-header": "header value"},
  "webhook_verify_ssl": true,
  "save_dicts": true,
  "type": "dump",
  "sens_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "partial_tables_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "partial_tables_exclude_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "output_path": "my_dump",
  "pg_dump_path": "/usr/lib/postgresql/17/bin/pg_dump",
  "ignore_privileges": false,
  "proc_count": 4,
  "proc_conn_count": 4
}'

Схема вебхук-запроса дампа

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Копируется из operation_id исходного запроса сканирования.
internal_operation_id строка Нет Внутренний идентификатор операции pg_anon, генерируемый автоматически. Присутствует только когда status имеет значение success или error. Может использоваться для сопоставления события webhook с данными операции и журналами, хранящимися в каталоге /runs. Также используется в конечных точках Operation.
status_id целое число Да Числовой код статуса. Возможные значения: 2 — успех, 3 — ошибка, 4 — выполняется.
status строка Да Удобочитаемый статус. Возможные значения: success, error, in_progress.
webhook_metadata любой Нет Метаданные, передаются «как есть». Копируются из поля webhook_metadata запроса сканирования.
started строка Нет Временная метка начала операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
ended строка Нет Временная метка окончания операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
error строка Нет Сообщение об ошибке. Присутствует только если status = error.
error_codeстрокаНетМашиночитаемый код ошибки для сопоставления i18n. Присутствует только если status = error.
run_options JSON Нет Снимок параметров выполнения операции. Полезно для анализа, отладки и повторного запуска операции. Присутствует только когда status = success или error.
size целое число Нет Размер дампа в байтах.

Ответы

Код состояния Описание Компонент
201 Операция успешно запущена -
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError
I.3.12.1.8. Выполнение восстановления #

POST /api/stateless/restore

Описание

Запускает pg_anon в режиме Restore в фоне.

Жизненный цикл операции:

  1. Клиент вызывает эту конечную точку.

  2. API возвращает один из следующих кодов статуса:

    • 200 — операция восстановления была успешно запущена.

    • 400 или 422 — некорректный запрос; операция не начата.

  3. Сервис отправляет вебхук-запрос со статусом in_progress на webhook_status_url. Формат полезной нагрузки описан в схеме вебхук-запроса восстановления.

  4. Операция выполняется в фоновом режиме.

  5. Если во время обработки происходит ошибка, сервис отправляет вебхук-запрос со статусом error.

  6. Если операция завершается успешно, служба отправляет вебхук-запрос со статусом success.

Схема запроса восстановления

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Принимает любую строку. Возвращается без изменений в запросах webhook.
db_connection_params DbConnectionParams Да Учетные данные для подключения к исходной базе данных.
webhook_status_url строка Да URL обратного вызова, который принимает POST-запросы в формате, описанном в схеме вебхук-запроса восстановления.
webhook_metadata любой Нет Произвольные метаданные. Отправляются без изменений в запросах webhook.
webhook_extra_headers JSON Нет Дополнительные HTTP-заголовки, добавляемые к запросам webhook. Полезно для интеграции, например, чтобы включить заголовок Authorization.
webhook_verify_ssl boolean Нет Включает или отключает проверку SSL-сертификата для запросов webhook.
save_dicts boolean Нет Сохраняет все входные и выходные словари в каталог runs. Полезно для отладки или интеграции. По умолчанию: false.
type строка Нет Определяет тип восстановления. Варианты: restore, sync-struct-restore, sync-data-restore. По умолчанию: restore.
input_path строка Да Путь к дампу для восстановления, относительно /path_to_pg_anon/output. Пример: "my_dump" восстановит из /path_to_pg_anon/output/my_dump.
partial_tables_dict_contents массив DictionaryContent Нет Содержимое словаря таблиц, указывающее таблицы, которые нужно включить в частичное восстановление
partial_tables_exclude_dict_contents массив DictionaryContent Нет Содержимое словаря таблиц, указывающее таблицы, которые нужно исключить из частичного восстановления
pg_restore_path строка Нет Путь к инструменту Postgres pg_restore. По умолчанию: /usr/bin/pg_restore.
pg_restore_optionsstringНетДополнительные параметры, передаваемые непосредственно утилите pg_restore. Пример: "--no-comments --no-table-access-method".
drop_custom_check_constr boolean Нет Удаляет все ограничения CHECK, содержащие пользовательские процедуры, чтобы избежать снижения производительности при загрузке данных. По умолчанию: false.
clean_db boolean Нет Очищает существующие объекты базы данных перед восстановлением. Взаимоисключающий с drop_db.
drop_db boolean Нет Удаляет целевую базу данных перед восстановлением. Взаимоисключается с clean_db.
ignore_privileges boolean Нет Игнорировать привилегии из исходной базы данных.
proc_count целое число Нет Количество процессов, используемых для многопроцессорной обработки. По умолчанию: 4.
proc_conn_count целое число Нет Количество подключений к базе данных, выделяемых на каждый процесс для операций ввода-вывода. По умолчанию: 4.

Пример

curl -X POST http://127.0.0.1:8000/api/stateless/restore \
-H "Content-Type: application/json" \
-d '{
  "operation_id": "my-uniq-scan-id-0001",
  "db_connection_params": {
     "host": "localhost",
     "port": "5432",
     "db_name":  "source_db",
     "user_login": "postgres",
     "user_password":  "postgres"
  },
  "webhook_status_url": "https://my-service/pg-anon-result-processor",
  "webhook_metadata": {"extra_field_1": "extra_data", "extra_field_2": {"fld1": [1,2,3], "fld2": 123}},
  "webhook_extra_headers": {"Authorization": "Api-key my_super_secret_api_key", "X-my-service-extra-header": "header value"},
  "webhook_verify_ssl": true,
  "save_dicts": true,
  "type": "restore",
  "input_path": "my_dump",
  "partial_tables_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "partial_tables_exclude_dict_contents": [{
    "name": "sens dict for email anonymization",
    "content": "{\"dictionary\": [{\"schema\": \"public\", \"table\": \"users\", \"fields\": {\"email\": \"md5(email)\"}}, {\"schema\": \"public\", \"table\": \"clients\", \"fields\": {\"email\": \"md5(email)\"}}]}"
  }],
  "pg_restore_path": "/usr/lib/postgresql/17/bin/pg_restore",
  "drop_custom_check_constr": false,
  "clean_db": false,
  "drop_db": false,
  "ignore_privileges": false,
  "proc_count": 4,
  "proc_conn_count": 4
}'

Схема вебхук-запроса восстановления

Поле Тип Обязательное Описание
operation_id строка Да Внешний идентификатор операции. Копируется из operation_id исходного запроса сканирования.
internal_operation_id строка Нет Внутренний идентификатор операции pg_anon, генерируемый автоматически. Присутствует только когда status имеет значение success или error. Может использоваться для сопоставления события webhook с данными операции и журналами, хранящимися в каталоге /runs. Также используется в конечных точках Operation.
status_id целое число Да Числовой код статуса. Возможные значения: 2 — успех, 3 — ошибка, 4 — выполняется.
status строка Да Удобочитаемый статус. Возможные значения: success, error, in_progress.
webhook_metadata любой Нет Метаданные, передаются «как есть». Копируются из поля webhook_metadata запроса сканирования.
started строка Нет Временная метка начала операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
ended строка Нет Временная метка окончания операции в формате ISO8601 (UTC+0). Присутствует только для статусов success или error.
error строка Нет Сообщение об ошибке. Присутствует только если status = error.
error_codeстрокаНетМашиночитаемый код ошибки для сопоставления i18n. Присутствует только если status = error.
run_options JSON Нет Снимок параметров выполнения операции. Полезно для анализа, отладки и повторного запуска операции. Присутствует только когда status = success или error.

Ответы

Код состояния Описание Компонент
201 Операция успешно запущена -
400 Неверный запрос ErrorResponse
500 Внутренняя ошибка сервера ErrorResponse
422 Ошибка проверки данных HTTPValidationError

I.3.12.2. Методы API для интеграции со сторонними сервисами #

I.3.12.2.1. Список операций #

GET /operation

Описание

Возвращает список директорий фоновых операций (сканирование, дамп, восстановление). Включаются только операции, выполненные с включённой опцией save_dicts. Полезно для целей интеграции.

Параметры запроса списка операций

Поле Тип Обязательное Описание
date_before дата Нет Фильтр: операции до этой даты. Формат даты ISO 8601
date_after дата Нет Фильтр: операции после этой даты. Формат даты ISO 8601

Пример

curl -X GET http://127.0.0.1:8000/operation?date_after=2025-01-01&date_before=2025-12-31

Ответы

Код состояния Описание Компонент
200 Список путей операций массив строк
422 Ошибка проверки данных HTTPValidationError
I.3.12.2.2. Подробности операции #

GET /operation/{internal_operation_id}

Описание

Возвращает подробную информацию о фоновом процессе (сканирование, дамп, восстановление). Включает только операции, выполненные с включённым параметром save_dicts. Полезно для целей интеграции.

Параметры запроса сведений об операциях

Поле Тип Обязательное Описание
internal_operation_id строка Да Внутренний идентификатор операции pg_anon.

Пример

curl -X GET http://127.0.0.1:8000/operation/c6c98133-856f-46b3-ba9e-3a0092b8d9aa

Ответы

Код состояния Описание Компонент
200 Подробности операции OperationDataResponse
404 Каталог операции не найден HTTPValidationError
422 Ошибка проверки данных HTTPValidationError
I.3.12.2.3. Данные операции удаления #

DELETE /operation/{internal_operation_id}

Описание

Удаляет рабочий каталог операции в /runs. Также удаляет каталог дампа из выходного пути, если тип операции — dump.

Пример

curl -X DELETE http://127.0.0.1:8000/operation/c6c98133-856f-46b3-ba9e-3a0092b8d9aa

Параметры запроса данных операции удаления

Поле Тип Обязательное Описание
internal_operation_id строка Да Внутренний идентификатор операции pg_anon.

Ответы

Код состояния Описание Компонент
204 Данные операции успешно удалены -
400 Неверный запрос ErrorResponse
422 Ошибка проверки данных HTTPValidationError
500 Внутренняя ошибка сервера ErrorResponse
I.3.12.2.4. Журналы операций #

GET /operation/{internal_operation_id}/logs

Описание

Возвращает вывод журнала для фоновой операции (сканирование, дамп, восстановление). Включаются только операции, выполненные с включённым параметром save_dicts. Полезно для целей интеграции.

Operations logs request body schema

Имя Тип Обязательный Описание
internal_operation_id строка Да Внутренний идентификатор операции pg_anon.
tail_lines целое число Нет Количество строк журнала для чтения с конца файла. По умолчанию: 1000

Пример

curl -X GET http://127.0.0.1:8000/operation/c6c98133-856f-46b3-ba9e-3a0092b8d9aa/logs

Ответы

Код состояния Описание Компонент
200 Успешный ответ массив строк
422 Ошибка проверки данных HTTPValidationError

I.3.13. Общие схемы #

I.3.13.1. DbConnectionParams #

Поле Тип Обязательное Описание
host строка Да Хост базы данных.
port целое число Да Порт базы данных.
db_name строка Да Имя базы данных.
user_login строка Да Пользователь базы данных.
user_password строка Да Пароль пользователя базы данных.

I.3.13.2. DictionaryContent #

Поле Тип Обязательное Описание
name строка Да Имя словаря. Например, может использоваться как имя файла словаря
content строка Да Содержимое словаря, используемое для обработки операций
additional_info любой Нет Дополнительные данные для целей интеграции. Будут отправлены на вебхук "как есть".

I.3.13.3. DictionaryMetadata #

Поле Тип Обязательное Описание
name строка Да Имя словаря. Например, может использоваться как имя файла словаря
additional_info любой Нет Дополнительные данные для целей интеграции. Будут отправлены на вебхук "как есть".

I.3.13.4. OperationDataResponse #

Поле Тип Обязательное Описание
run_status RunStatus Да Статус операции.
run_options JSON Да Снимок параметров выполнения операции. Полезно для анализа, отладки и повторного запуска операции.
dictionaries DictionariesData Да Используемое и полученное содержимое словарей по типам.
extra_data JSON Нет Для операций дампа содержит информацию о размере дампа. В других случаях пусто.

I.3.13.5. RunStatus #

Поле Тип Обязательное Описание
status_id целое число Да Числовой код статуса. Возможные значения: 2 — успех, 3 — ошибка.
status строка Да Удобочитаемый статус. Возможные значения: success, error.
started строка Нет Временная метка начала операции в формате ISO8601 (UTC+0).
ended строка Нет Временная метка окончания операции в формате ISO8601 (UTC+0).

I.3.13.6. DictionariesData #

Поле Тип Обязательное Описание
meta_dict_files массив содержимого словаря Нет Содержимое входного мета-словаря.
prepared_sens_dict_files массив содержимого словаря Нет Содержимое входного чувствительного словаря.
prepared_no_sens_dict_files массив содержимого словаря Нет Содержимое входного нечувствительного словаря.
partial_tables_dict_files массив содержимого словаря Нет Содержимое входного словаря таблиц.
partial_tables_exclude_dict_files массив содержимого словаря Нет Содержимое входного словаря таблиц.
output_sens_dict_file DictionaryContent Нет Содержимое выходного чувствительного словаря.
output_no_sens_dict_file DictionaryContent Нет Содержимое выходного нечувствительного словаря.

I.3.13.7. ViewDataResponse #

Поле Тип Обязательное Описание
status_id integer Да Целочисленный код статуса операции. Может быть: 2 — успех, 3 — ошибка
status строка Да Удобочитаемый статус операции. Может быть: success, error
content ViewDataContent Нет Данные результата операции

I.3.13.8. ViewDataContent #

Поле Тип Обязательное Описание
schema_name строка Да Имя схемы
table_name строка Да Имя таблицы
field_names массив Да Имена полей таблицы. Необходимо для отображения заголовка таблицы
total_rows_count целое число Да Общее количество строк в таблице. Полезно для постраничного вывода
rows_before массив Да Исходные данные строк "как есть" без анонимизации
rows_after массив Да Анонимизированные строки, для отображения того, как будет работать анонимизация с исходными данными

I.3.13.9. ViewFieldsResponse #

Поле Тип Обязательное Описание
status_id integer Да Целочисленный код статуса операции. Может быть: 2 — успех, 3 — ошибка
status строка Да Удобочитаемый статус операции. Может быть: success, error
content ViewFieldsContent Нет Данные результата операции

I.3.13.10. ViewFieldsContent #

Поле Тип Обязательное Описание
schema_name строка Да Имя схемы
table_name строка Да Имя таблицы
field_name строка Да Имя поля
type строка Да Тип данных поля
dict_data DictionaryMetadata Нет Соответствующие метаданные словаря, содержащие правило анонимизации
правило строка Нет Соответствующее правило анонимизации, если поле является конфиденциальным

I.3.13.11. PreviewSchemasResponse #

ПолеТипОбязательноеОписание
status_idintegerДаЦелочисленный код статуса операции. Может быть: 2 — успех, 3 — ошибка
статусстрокаДаЧеловекочитаемый статус операции. Может быть: success, error
содержимоемассив строкНетСписок имен схем

I.3.13.12. ПредварительныйПросмотрСхемыТаблицОтвет #

ПолеТипОбязательноеОписание
status_idintegerДаЦелочисленный код статуса операции. Может быть: 2 — успех, 3 — ошибка
статусстрокаДаЧеловекочитаемый статус операции. Может быть: success, error
содержимоемассив PreviewTableContentНетСписок таблиц с информацией о чувствительности

I.3.13.13. PreviewTableContent #

ПолеТипОбязательноеОписание
table_nameстрокаДаИмя таблицы
is_sensitivebooleanДаУказывает, соответствует ли таблица словарю конфиденциальных данных
is_excludedbooleanДаУказывает, исключена ли таблица с помощью dictionary_exclude
полямассив PreviewFieldContentНетСписок полей с их типами и информацией о чувствительности

I.3.13.14. ПредварительныйПросмотрСодержимого #

ПолеТипОбязательноеОписание
field_nameстрокаДаИмя поля
типстрокаДаТип данных поля
is_sensitivebooleanДаУказывает, соответствует ли поле правилу анонимизации
правилострокаНетСоответствующее правило анонимизации, если поле является конфиденциальным

I.3.13.15. ErrorResponse #

Поле Тип Обязательное Описание
error_codeстрокаДаМашиночитаемый код ошибки для сопоставления i18n.
сообщениестрокаДаЧеловекочитаемое сообщение об ошибке.

I.3.13.16. HTTPValidationError #

Поле Тип Обязательное Описание
detail массив Да Подробности ошибки.

I.3.13.17. ValidationError #

Поле Тип Обязательное Описание
loc массив Да Неверный параметр.
msg строка Да Сообщение об ошибке.
type строка Да Тип ошибки.