Куда утекают чувствительные данные
Почему номер паспорта оказывается в таблице, которая никого не должна касаться
В крупной организации есть понимание: вот чувствительные данные. Паспортные номера — в HR-системе. Номера карт — в платёжном модуле. История болезней — в медицинской подсистеме. Всё закрыто, доступ ограничен, compliance-офицер спокоен.
А потом выясняется, что номер паспорта — в аналитической витрине, в агрегированном отчёте, в кэше BI-системы. Никто не переносил его туда намеренно. Он попал сам — через цепочку трансформаций, о которой никто не думал.
Это не утечка в классическом смысле. Никто не взломал систему. Данные переместились по штатным каналам. И именно поэтому их там никто не ожидал найти.
Как данные расходятся без взлома
В большом хранилище данных постоянно происходит следующее: один процесс читает данные из одной таблицы и записывает результат в другую. ETL-процесс. Агрегация. Ночная синхронизация. VIEW, который соединяет несколько источников в одном запросе.
Каждый шаг выглядит безобидно. Никто не копирует «номер паспорта» явно — копируется «идентификатор записи», который оказывается номером паспорта. Или агрегируется таблица, одно из полей которой содержит персональные данные. Или VIEW включает колонку, которую аналитик добавил «для удобства».
Через пять таких шагов чувствительные данные оказываются в таблице, которая изначально не имела к ним никакого отношения. Формально — это не нарушение. Данные прошли штатные процессы. Фактически — compliance-нарушение: данные находятся там, где по документации их нет.
Проблема наследования чувствительности
Ключевой концепт здесь — наследование чувствительности.
Если колонка A содержит персональные данные, и в каком-то процессе создаётся колонка B, которая вычисляется из A — колонка B тоже чувствительна. Даже если она называется DERIVED_VALUE, даже если в ней данные в другом формате, даже если её создавал другой отдел и другая команда.
Чувствительность не исчезает при трансформации. Она наследуется.
На одном шаге это очевидно. На пяти шагах — уже не очевидно. На десяти — никто не знает. В реальных корпоративных хранилищах с многолетней историей цепочки таких трансформаций уходят на глубину, которую вручную не отследить.
Почему таблица — недостаточная единица контроля
Традиционные инструменты контроля данных работают на уровне таблиц. «Таблица HR_EMPLOYEES содержит персональные данные» — это знание. Доступ к таблице ограничен.
Но трансформации работают на уровне колонок.
Запрос берёт из HR_EMPLOYEES только поля EMPLOYEE_ID и DEPARTMENT_CODE. Присоединяет к PAYROLL_SUMMARY. Записывает результат в аналитическую витрину. Там нет ни имён, ни паспортов — только идентификаторы.
Но EMPLOYEE_ID в этом контексте — это персональные данные: по нему можно однозначно идентифицировать человека. Таблица HR_EMPLOYEES была защищена. Конкретная колонка вышла из-под защиты и ушла в витрину — через абсолютно штатный процесс.
Контроль на уровне таблиц этого не видит. Нужен контроль на уровне колонок — отслеживание, откуда пришло каждое поле в каждой таблице.
Неожиданные потоки: то, что никто не подозревал
Самая неприятная категория — неожиданные чувствительные потоки.
Это колонки, которые никто изначально не считал чувствительными, но которые стали таковыми через многоуровневые трансформации.
Пример: есть таблица с обезличенными идентификаторами клиентов. Сама по себе — не чувствительна. Есть таблица транзакций — тоже не чувствительна, только суммы. Но если соединить их по идентификатору и добавить временны́е метки — получается достаточно данных для ре-идентификации конкретного человека. Ни одна из исходных таблиц не была помечена как чувствительная. Производная — является.
В регуляторном понимании это нарушение — независимо от того, знала ли организация о существовании этого потока. «Не знали» не освобождает от ответственности. Именно поэтому регуляторы требуют реестры обработки данных — и именно поэтому их так сложно поддерживать в актуальном состоянии.
Скорость изменений против скорости документации
Добавляется проблема времени.
Хранилище данных меняется постоянно. Новые таблицы, новые ETL-процессы, реструктуризация схем. В современных организациях цикл разработки — дни, иногда часы. Схема обновляется быстрее, чем команды успевают обновить документацию.
Это означает, что даже полностью корректная карта чувствительных потоков, составленная сегодня, завтра будет частично устаревшей. Новый ETL-процесс добавил поток, которого нет в реестре. Перенесённая таблица изменила маршрут существующего потока. Удалённое поле оборвало цепочку — или создало новую через другой путь.
Ручное сопровождение такой карты в организации с тысячами таблиц и сотнями процессов — практически невозможно. Не потому что люди недостаточно старательны, а потому что скорость изменений превышает человеческие возможности отслеживания.
Аудируемость: почему важно знать «откуда»
Когда чувствительные данные обнаруживаются там, где их не должно быть, первый вопрос — откуда они взялись?
Для проверки регулятором это не риторический вопрос. 152-ФЗ требует точного знания, через какие процессы проходят персональные данные. Банк России при проверке финансовой организации ждёт журнала движения данных. Ответ «мы не знаем, как туда попало» — не принимается.
Именно здесь возникает принципиальное различие между подходами к автоматическому отслеживанию.
Детерминированный парсинг SQL — медленнее, ограниченнее, требует разбора каждого запроса — но даёт точный ответ: «вот эта колонка появилась вот здесь, в этом запросе, через этот JOIN». Каждый вывод traceable к конкретной строке кода. Это аудит-след в строгом смысле: воспроизводимый, проверяемый, опровержимый.
Семантический поиск по корпусу запросов — гибче, покрывает то, что парсер не может разобрать — но не даёт такой же прямой трассировки. Он говорит «вероятно, связано с этим контекстом». Для compliance-отчётности «вероятно» — недостаточно.
Это не значит, что один подход лучше другого. Это значит, что у них разные роли в системе контроля: один строит доказательную базу, другой заполняет пробелы там, где доказательная база недостижима.
Что ищут регуляторы
Регуляторные требования в этой области конкретны.
- 152-ФЗ «О персональных данных» — оператор обязан знать и документировать, где и как обрабатываются персональные данные. Роскомнадзор при проверке запрашивает перечень информационных систем и их описание. Автоматически обновляемая карта потоков — это не удобство, это то, что должно быть в любой момент.
- Приказы ФСТЭК (№ 17, № 21) — требования к защите информационных систем персональных данных. Состав мер включает контроль потоков информации: система должна не допускать передачу данных за пределы установленного периметра. Без понимания, куда данные расходятся, такой контроль невозможен.
- Положения Банка России (ГОСТ Р 57580, 382-П) — для финансовых организаций: управление доступом и контроль информационных потоков входят в обязательный набор мер. Пропущенный поток персональных или финансовых данных — это не технический инцидент, это нарушение требований регулятора.
Проблема в том, что ни один из регуляторов не уточняет, как именно нужно обеспечить такое знание. Они формулируют требование к результату — «знай, где твои данные». Как его достичь при тысячах таблиц и постоянно меняющейся схеме — это вопрос, который организации решают самостоятельно.
Граф — это возможность, не факт
Построить граф линеажа — необходимый первый шаг. Но граф отвечает на вопрос «что может течь», а не «что текло на самом деле».
Процесс ETL настроен и потенциально переносит поле с персональными данными в аналитическую витрину. Это видно в статическом графе. Но запускался ли этот процесс вчера? Неделю назад? Вообще когда-либо в продуктиве? Был ли он отключён после инцидента полгода назад? А может, запускается только в конце квартала?
Для compliance это принципиальная разница. Регулятора интересует не абстрактная возможность потока, а конкретные факты: какой процесс, в какое время, с какими данными выполнился. Без истории запусков граф линеажа — это карта дорог, на которой не показано, где реально проезжали машины.
Полноценная система контроля чувствительных потоков должна совмещать статический граф с операционной историей: что запускалось, когда, успешно ли завершилось, какой объём данных прошёл. Только тогда ответ на вопрос «где сейчас находятся чувствительные данные» становится не теоретическим, а фактическим.
Эффект кучи: таблица как общий приёмник
Отдельная задача, которую граф линеажа не решает сам по себе — это смешанная таблица: когда несколько процессов пишут в одну и ту же таблицу через UNION или параллельные INSERT, и одни из них несут чувствительные данные, а другие — нет.
Типичный сценарий: есть центральная таблица событий. В неё пишут пять ETL-процессов. Один загружает данные о платёжных операциях — чувствительно. Второй — данные о складских перемещениях — не чувствительно. Третий — кадровые изменения — чувствительно. Четвёртый и пятый — технические логи — не чувствительно.
Таблица как объект в базе данных одна. Но содержимое строк в ней — разное по природе и по степени защиты.
Как теперь пометить эту таблицу? Если сказать «таблица чувствительная» — любой запрос к ней попадает под ограничения, включая запросы, которые читают только складские данные. Если сказать «не чувствительная» — запросы к платёжным строкам остаются без контроля.
Ни один из вариантов не работает. Нужен ответ на уровне строк: какие именно записи попали в таблицу из чувствительного источника? Но традиционный линеаж этого не знает — он видит, что процесс A пишет в таблицу T, и что процесс B тоже пишет в таблицу T. Он не видит, какие именно строки принадлежат A, а какие — B.
Ещё сложнее — следующий шаг. Если downstream-запрос читает из этой таблицы с фильтрацией по типу события — он, возможно, никогда не затрагивает чувствительные строки. А если без фильтрации — затрагивает всегда. Статический линеаж не различает эти два случая: оба выглядят как «запрос читает таблицу T».
Это и есть эффект кучи: таблица превращается в общий приёмник, где чувствительные и нечувствительные данные перемешаны на уровне строк, и разобрать их обратно без истории запусков и контекста фильтрации — невозможно.
Где проходит граница сложности
На рынке есть специализированные инструменты для data lineage: Collibra, Informatica, Manta и другие. Зрелые продукты — умеют строить граф зависимостей, включая колоночный уровень, и подключаться к типовым корпоративным источникам.
Сложность начинается там, где задача выходит за рамки «нарисовать граф»: нужно не просто знать, что поток существует, но и понять — чувствителен ли он и почему.
- Разметка первичных источников — кто и как решает, что именно считается чувствительным? Список «таблица HR — персональные данные» очевиден. Но
DERIVED_SCORE, вычисленный из поведенческих паттернов, — это тоже персональные данные? А агрегат по идентификатору — при каком уровне детализации он перестаёт быть обезличенным? Эти вопросы не решаются автоматически: они требуют участия юриста, compliance-офицера и владельца данных. Инструмент может зафиксировать принятое решение — но не принять его. - Аналитика по потокам — после того как граф построен и разметка сделана, вопросы становятся сложнее: на какую глубину расходятся чувствительные данные в этой конкретной схеме? Какие производные таблицы получили чувствительность неочевидным путём — через пять трансформаций, о которых никто не думал в момент их создания? Это не навигация по графу вручную — это аналитика, которая требует автоматического обхода и интерпретации смысла потоков.
- Динамический SQL остаётся открытым вызовом для всей отрасли: запросы, которые приложение собирает строками на лету, не существуют как текст до момента выполнения. Это ограничение касается любого инструмента, который работает со статическим кодом.
Граница проходит не между «хорошими» и «плохими» инструментами — а между тем, что решается построением графа, и тем, что требует понимания смысла потоков.
Данные утекают не потому что кто-то хотел плохого. Они утекают потому что каждый шаг был разумным — а их совокупность никто не видел целиком. Увидеть целиком — это и есть задача.