Аудитория: DPO (ответственный за ПДн), ИБ-служба, юрист, суперадминистратор. Закрывает вопросы: №2 («что вы делаете с ПДн сотрудников?»), №4 («это не слежка?»). Сценарии: S2 — сотрудник требует показать/удалить свои данные; защита перед проверкой.
В рабочих таблицах «Лицензиара» нет ФИО и табельных номеров — только непрозрачные идентификаторы hex(64). Связь «идентификатор ↔ человек» хранится в отдельном изолированном сейфе (Identity Vault), который виден только роли DPO и только при явном раскрытии по основанию (номер приказа). Каждое раскрытие пишется в аудит-журнал ФЗ-152. Поэтому продукт — это аудит лицензий и эффективности ПО, а не слежка за людьми: он оперирует обезличенными агрегатами, а персонификация — исключение, протоколируемое и обоснованное.
источник (KSC/1С/syslog) ПРИЁМ (api) БД
┌──────────────────┐ сырой табельный ┌──────────────────┐ obezlich. ┌─────────────────┐
│ tabel_no=«12345» │ ───────────────► │ anonymize(tenant,│ ──────────► │ user_id = a3f9… │
│ raw_product=… │ по сети, │ tabel_no) │ hex(64) │ (ФИО/табельных │
└──────────────────┘ только транзит │ Стрибог-256 │ │ в фактах НЕТ) │
└──────────────────┘ └─────────────────┘
СЫРЬЁ НИГДЕ НЕ ХРАНИТСЯ ─────────────┘ │
▼
┌───────────────────────────────────────────┐
│ vault.user_identity (изолят, RLS dpo-only) │
│ user_id hex(64) ↔ табельный/ФИО │
└───────────────────────────────────────────┘Ключевой принцип: сырой табельный номер существует только в момент приёма и сразу превращается в user_id. Обезличивает именно приём (функция ingest_activity), а не коллектор: по сети сырьё проходит транзитом, в таблицу фактов sam.activity_facts попадает только hex(64). То же касается «сырого имени ПО» (raw_product) — оно используется для распознавания системы и не сохраняется.
- Алгоритм — ГОСТ Р 34.11-2012 «Стрибог-256». Это не СКЗИ (см. статью 01).
- Вход:
ANON_SALT | tenant_id | табельный→ выходhex(64). Соль из env, не в БД и не в логах. - Изоляция арендаторов встроена в id:
tenant_idвходит в хеш, поэтому один и тот же
табельный у разных арендаторов даёт разные идентификаторы — пространства не пересекаются.
Точная позиция перед аттестатором. Механизм обратим при наличии сейфа — это псевдонимизация (ст. 3 п. 9), поэтому система в целом остаётся ИСПДн, а сейф — её носитель ПДн. Операционная же плоскость (sam) обезличена для всех без доступа к сейфу. Заявление «портал вообще не ИСПДн» — некорректно и не делается. Сегодня сейф — это логический изолят (отдельная схема + RLS в той же СУБД); физический вынос сейфа в отдельный сервис — запланированное усиление границы аттестации.Сейф — это отдельная схема `vault` (таблица vault.user_identity), заводимая первой же миграцией схемы БД и доступная только через серверный слой под RLS-политикой.
- Хранит связь
user_id (hex64) ↔ табельный/ФИОв отдельной схеме `vault`, а не вsam. - RLS-политика `vault_dpo_only`: строки видны только при роли
dpo. Любая другая роль
(включая viewer, it_admin, superadmin) видит в сейфе 0 строк — это проверяется тестом приёмки.
- Раскрытие —
POST /api/{tenant}/vault/resolveс обязательным полемbasis(например,
номер и дата приказа/служебной записки). Без основания раскрытия нет.
Каждый вызов vault/resolve пишет запись `VAULT_RESOLVE` в аудит-лог: кто (роль/логин), когда, по какому основанию. Журнал виден на экране /audit (роль dpo/superadmin). Это и есть доказательство для проверки: персонификация всегда оставляет след с обоснованием.
S2a. Сотрудник: «покажите, какие мои данные вы собираете». В фактах активности его данные представлены непрозрачным user_id; ФИО/табельный — в сейфе Vault. DPO раскрывает соответствие по основанию (приказ/запрос субъекта ПДн) через vault/resolve; факт раскрытия фиксируется в аудите. Сотруднику предъявляются его агрегаты активности (дни/транзакции по системам), а не «слежка».
S2b. Сотрудник: «удалите мои данные». Удаляется связь в vault.user_identity (соответствие id↔человек). После этого обезличенные факты перестают быть персональными данными — субъект по ним не определяется. Операция — ответственность DPO, под основание и запись в аудит.
S2c. Профсоюз/работник: «это система слежки за людьми?». Нет. Продукт считает утилизацию лицензий и эффективность ПО на обезличенных агрегатах. Он не пишет содержимое экранов/нажатия/переписку — только факт «в системе X в день D было N транзакций и M минут сессии». Персонификация технически отделена, ограничена ролью DPO и требует основания.
vault.user_identityпод рольюviewer→ 0 строк (RLS-политикаvault_dpo_only;
проверяется тестом приёмки «viewer видит 0»).
- Пример записи
VAULT_RESOLVEна экране/auditс заполненнымbasis. - Исходник приёма: в таблицу фактов пишется только
user_id = anonymize(...),
сырой табельный никуда не сохраняется.
▸Исходник приёма телеметрии: обезличивание на месте, сырьё не хранится
for rec in records:
sys_id = code_to_id.get(rec.sys_code)
if sys_id is None:
# Фолбэк: распознаём систему по сырому имени ПО (Recognition Parser).
code = recognition.recognize(getattr(rec, "raw_product", "") or "")
sys_id = code_to_id.get(code) if code else None
...
user_id = anonymize(tenant_id, rec.tabel_no) # <- сырой табельный НЕ хранится
cur.execute(
"""INSERT INTO sam.activity_facts
(tenant_id, sys_id, user_id, activity_date, tx_count, session_minutes, is_active_day)
VALUES (%s,%s,%s,%s,%s,%s,%s)
ON CONFLICT (tenant_id, sys_id, user_id, activity_date) DO UPDATE ...""",
(tenant_id, sys_id, user_id, rec.activity_date, rec.tx_count, rec.session_minutes, is_active),
)В INSERT уходит user_id (hex64), а rec.tabel_no и rec.raw_product существуют только как локальные переменные на время обработки записи — в таблицу они не попадают.
- Заготовка заключения для аттестатора ИСПДн — готовый пакет фактов о защите ПДн
(его подписывает аттестатор/орган заказчика).
▸Фрагмент заключения: защита ПДн и журналирование (ФЗ-152)
| Требование | Реализация | Доказательство |
|---|---|---|
| Связь идентификатор↔субъект изолирована | Identity Vault в отдельной схеме, доступ только роли DPO | RLS vault_dpo_only, тест test_vault_blocked_for_non_dpo |
| Раскрытие — только по основанию, с фиксацией | резолв идентичности пишет запись VAULT_RESOLVE с номером приказа | тест test_vault_resolve_dpo_writes_audit |
| Журнал доступа (ФЗ-152) | партиционированная таблица аудита действий fz152_audit | проверка наличия и заполнения журнала |
| Изоляция данных арендаторов | RLS tenant_isolation (FORCE) на всех таблицах; роль приложения — не суперюзер | тесты test_rggu_isolated_from_artek, test_rls_tenant_isolation |
- Vault-операции требуют одинаковую `ANON_SALT` на приёме и при сопоставлении. Если соль
на сиде/приёме отличается от текущей — посчитанные user_id не совпадут с теми, что в сейфе, и raw→id «не найдётся» (на стенде поэтому везде ANON_SALT=test-salt). Это не дефект, а следствие того, что соль — часть личности инсталляции.
- Раскрытие без `basis` невозможно — это by design. Не обходите: запись в аудит и
основание и есть ваша защита при проверке ФЗ-152.
- demo_public — публичный обезличенный арендатор. Там нет реальных людей и он доступен
только на чтение; не используйте его как площадку для реальных ПДн.
Связанные статьи: 01 — Не СКЗИ · 04 — Механизм сбора · 07 — Роли и доступ.