<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Yuriy Gavrilov: posts tagged Security</title>
<link>https://gavrilov.info/tags/security/</link>
<description>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</description>
<author></author>
<language>en</language>
<generator>Aegea 11.4 (v4171e)</generator>

<itunes:owner>
<itunes:name></itunes:name>
<itunes:email>yvgavrilov@gmail.com</itunes:email>
</itunes:owner>
<itunes:subtitle>Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov</itunes:subtitle>
<itunes:image href="https://gavrilov.info/pictures/userpic/userpic-square@2x.jpg?1643451008" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Генерация синтетических данных с помощью SDV: от идеи до готовой таблицы в ClickHouse</title>
<guid isPermaLink="false">347</guid>
<link>https://gavrilov.info/all/generaciya-sinteticheskih-dannyh-s-pomoschyu-sdv-ot-idei-do-goto/</link>
<pubDate>Thu, 03 Sep 2026 00:49:26 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/generaciya-sinteticheskih-dannyh-s-pomoschyu-sdv-ot-idei-do-goto/</comments>
<description>
&lt;p&gt;Синтетические данные давно перестали быть просто «искусственной картинкой» — сегодня это полноценный инструмент для тестирования, разработки и даже обучения моделей машинного обучения. В этой статье я на примере реального кода покажу, как с помощью библиотеки &lt;b&gt;SDV ( &lt;a href="https://github.com/sdv-dev/sdv"&gt;Synthetic Data Vault &lt;/a&gt; )&lt;/b&gt; можно сгенерировать синтетическую копию существующей таблицы из ClickHouse, сохранив её статистические свойства и взаимосвязи.&lt;/p&gt;
&lt;p&gt;Весь код, который мы разберём, написан на Python и использует актуальную версию SDV. Спойлер: итоговый скрипт занимает меньше 80 строк, а результат — полностью готовая синтетическая таблица в вашей базе данных.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-240.png" width="1280" height="640" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Что такое SDV и зачем он нужен&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Synthetic Data Vault (SDV)&lt;/b&gt; — это Python-библиотека с открытым исходным кодом, которая стала фактическим стандартом для генерации синтетических табличных данных. Она была создана в MIT, а сегодня развивается компанией DataCebo.&lt;/p&gt;
&lt;p&gt;Главная идея SDV проста: вы даёте ей реальные данные, она обучает генеративную модель, а затем эта модель создаёт новые данные, которые &lt;b&gt;статистически неотличимы&lt;/b&gt; от оригинала, но при этом не содержат реальных записей.&lt;/p&gt;
&lt;p&gt;Ключевые возможности SDV:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Обучение на одном наборе данных&lt;/b&gt; — библиотека анализирует распределения, корреляции и зависимости между колонками.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Генерация новых записей&lt;/b&gt; — синтетические данные повторяют структуру и свойства оригинала.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Оценка качества&lt;/b&gt; — встроенные метрики показывают, насколько хорошо синтетика отражает реальные данные.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Поддержка разных типов данных&lt;/b&gt; — числовые, категориальные, даты, текстовые поля.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SDV умеет работать с одиночными таблицами, связанными таблицами и даже последовательными данными.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Какие синтезаторы предлагает SDV&lt;/h3&gt;
&lt;p&gt;SDV предлагает несколько алгоритмов (синтезаторов) на выбор. В нашем примере мы используем &lt;b&gt;`GaussianCopulaSynthesizer`&lt;/b&gt; — и вот почему.&lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Синтезатор&lt;/td&gt;
&lt;td style="text-align: center"&gt;Принцип работы&lt;/td&gt;
&lt;td style="text-align: center"&gt;Скорость&lt;/td&gt;
&lt;td style="text-align: center"&gt;Когда использовать&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;GaussianCopulaSynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Классический статистический метод, моделирует данные через многомерное распределение&lt;/td&gt;
&lt;td style="text-align: center"&gt;Очень быстрый&lt;/td&gt;
&lt;td style="text-align: center"&gt;Рекомендуется для старта: быстрая работа, хорошее качество, прозрачность&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;CTGANSynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Генеративно-состязательная сеть (GAN)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Медленнее&lt;/td&gt;
&lt;td style="text-align: center"&gt;Для данных со сложными зависимостями или большим количеством категориальных признаков&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;TVAESynthesizer&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Вариационный автокодировщик&lt;/td&gt;
&lt;td style="text-align: center"&gt;Средняя&lt;/td&gt;
&lt;td style="text-align: center"&gt;Альтернатива GAN, требующая больше данных для обучения&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;`GaussianCopulaSynthesizer` отлично справляется со смешанными типами данных, которые встречаются в реальных таблицах: числа, строки, даты. При этом он обучается за секунды даже на десятках тысяч строк. Именно поэтому мы выбрали его для нашего примера.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Настройка окружения&lt;/h3&gt;
&lt;p&gt;Перед запуском кода нам потребуется установить несколько пакетов. В нашем проекте мы использовали `uv` — быстрый менеджер пакетов для Python.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;uv pip install torch==2.2.2
uv pip install &amp;quot;numpy&amp;lt;2&amp;quot;
uv pip install &amp;quot;scipy&amp;lt;1.13&amp;quot;
uv pip install sdv
uv pip install clickhouse-connect&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Важно&lt;/b&gt;: версии пакетов подобраны так, чтобы избежать конфликтов. На момент написания статьи `torch` версии 2.13.0 не имеет готовых сборок для macOS на Intel, поэтому мы используем `2.2.2`. Также важно зафиксировать `numpy&lt;2` и `scipy&lt;1.13` — более новые версии несовместимы с текущей версией `torch`.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;Полный код генерации синтетических данных&lt;/h3&gt;
&lt;p&gt;Ниже представлен итоговый скрипт `sdv_py_v5.py`, который мы будем разбирать. Он подключается к ClickHouse, загружает реальные данные, обучает синтезатор, генерирует синтетическую копию и сохраняет результат обратно в базу.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;import clickhouse_connect
import pandas as pd
import os
import warnings
from sdv.single_table import GaussianCopulaSynthesizer
from sdv.metadata import SingleTableMetadata

# Подавляем предупреждения (включая депрекацию)
warnings.filterwarnings(&amp;quot;ignore&amp;quot;)

# Правильный импорт для однотабличных отчётов
from sdmetrics.reports.single_table import QualityReport, DiagnosticReport

# ========== НАСТРОЙКИ ==========
CLICKHOUSE_HOST = 'localhost'
CLICKHOUSE_PORT = 18123
CLICKHOUSE_USER = 'default'
CLICKHOUSE_PASSWORD = 'changeme'
CLICKHOUSE_DATABASE = 'default'

SOURCE_TABLE = 'superstore'
SYNTHETIC_TABLE = f'{SOURCE_TABLE}_synt'
LIMIT_ROWS = 10000
NUM_SYNTHETIC_ROWS = None

# ========== ПОДКЛЮЧЕНИЕ ==========
client = clickhouse_connect.get_client(
    host=CLICKHOUSE_HOST,
    port=CLICKHOUSE_PORT,
    username=CLICKHOUSE_USER,
    password=CLICKHOUSE_PASSWORD,
    database=CLICKHOUSE_DATABASE
)

# ========== ЗАГРУЗКА ==========
query = f&amp;quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&amp;quot;
real_df = client.query_df(query)
print(f&amp;quot;Загружено {len(real_df)} строк&amp;quot;)

# Преобразуем числовые колонки (запятая → точка)
numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
    if col in real_df.columns and real_df[col].dtype == 'object':
        real_df[col] = real_df[col].str.replace(',', '.').astype(float)

# ========== МЕТАДАННЫЕ ==========
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)

if os.path.exists('metadata.json'):
    os.remove('metadata.json')
metadata.save_to_json('metadata.json')
print(&amp;quot;Метаданные сохранены в metadata.json&amp;quot;)

# ========== ОБУЧЕНИЕ ==========
print(&amp;quot;Начинаем обучение синтезатора...&amp;quot;)
synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)
print(&amp;quot;Обучение завершено&amp;quot;)

# ========== ГЕНЕРАЦИЯ ==========
if NUM_SYNTHETIC_ROWS is None:
    NUM_SYNTHETIC_ROWS = len(real_df)
synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)
print(f&amp;quot;Сгенерировано {len(synthetic_df)} строк&amp;quot;)

# ========== ПРЕДПРОСМОТР ==========
print(&amp;quot;\nОригинальные данные (первые 5 строк):&amp;quot;)
print(real_df.head())
print(&amp;quot;\nСинтетические данные (первые 5 строк):&amp;quot;)
print(synthetic_df.head())

# ========== ОЦЕНКА КАЧЕСТВА ==========
print(&amp;quot;\n--- Диагностика (проверка ошибок) ---&amp;quot;)
diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())
print(diagnostic)

print(&amp;quot;\n--- Оценка качества (статистическое сходство) ---&amp;quot;)
quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())
print(quality)

# ========== СОХРАНЕНИЕ В CLICKHOUSE ==========
client.command(f&amp;quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&amp;quot;)
client.insert_df(SYNTHETIC_TABLE, synthetic_df)
print(f&amp;quot;\nСинтетические данные загружены в таблицу {SYNTHETIC_TABLE}&amp;quot;)

# ========== СОХРАНЕНИЕ В CSV ==========
synthetic_df.to_csv('synthetic_table.csv', index=False)
print(&amp;quot;Синтетические данные также сохранены в synthetic_table.csv&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;h3&gt;Разбор кода по шагам&lt;/h3&gt;
&lt;h4&gt;1. Подключение к ClickHouse и загрузка данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;client = clickhouse_connect.get_client(
    host=CLICKHOUSE_HOST,
    port=CLICKHOUSE_PORT,
    username=CLICKHOUSE_USER,
    password=CLICKHOUSE_PASSWORD,
    database=CLICKHOUSE_DATABASE
)

query = f&amp;quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&amp;quot;
real_df = client.query_df(query)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Мы подключаемся к ClickHouse через библиотеку `clickhouse-connect` и загружаем данные из таблицы-источника в Pandas DataFrame. Лимит в 10 000 строк — разумный компромисс между качеством обучения и скоростью. Для большинства задач этого объёма достаточно, чтобы синтезатор уловил основные закономерности.&lt;/p&gt;
&lt;h4&gt;2. Предобработка числовых данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
    if col in real_df.columns and real_df[col].dtype == 'object':
        real_df[col] = real_df[col].str.replace(',', '.').astype(float)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В нашем примере числовые колонки хранятся в ClickHouse как строки с запятой в качестве десятичного разделителя (европейский формат). Перед обучением мы преобразуем их в числа с плавающей точкой — иначе SDV не сможет корректно обработать эти данные.&lt;/p&gt;
&lt;h4&gt;3. Создание метаданных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)
metadata.save_to_json('metadata.json')&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SDV автоматически определяет типы каждой колонки: числовые, категориальные, даты и т.д.. Метаданные сохраняются в JSON-файл — это полезно для воспроизводимости: в следующий раз вы сможете загрузить их, а не пересоздавать заново.&lt;/p&gt;
&lt;h4&gt;4. Обучение синтезатора&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Синтезатор «изучает» ваши данные: анализирует распределения каждой колонки, корреляции между ними, паттерны пропусков. Этот процесс занимает секунды даже на 10 000 строк.&lt;/p&gt;
&lt;h4&gt;5. Генерация синтетических данных&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Метод `sample()` создаёт нужное количество новых записей. В нашем случае мы генерируем столько же строк, сколько было в оригинале. При желании можно увеличить или уменьшить это число — синтезатор умеет масштабировать данные.&lt;/p&gt;
&lt;h4&gt;6. Оценка качества&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())

quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Этот этап — одна из сильных сторон SDV. Мы проверяем два аспекта:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Диагностика&lt;/b&gt; (Data Validity + Data Structure) — проверяет, что синтетические данные корректны по типам и структуре. В нашем случае — 100%.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Quality Report&lt;/b&gt; — оценивает статистическое сходство с реальными данными по двум метрикам:
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Column Shapes Score&lt;/b&gt; (90.77%) — насколько хорошо совпадают распределения отдельных колонок.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Column Pair Trends Score&lt;/b&gt; (37.71%) — насколько хорошо сохранились попарные зависимости между колонками.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Общий Score 64.24% — это нормальный результат для демонстрационного примера. Для улучшения качества можно переключиться на `CTGANSynthesizer` или увеличить объём обучающих данных.&lt;/p&gt;
&lt;h4&gt;7. Сохранение в ClickHouse&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;client.command(f&amp;quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&amp;quot;)
client.insert_df(SYNTHETIC_TABLE, synthetic_df)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Финальный шаг: создаём новую таблицу с той же структурой, что и исходная, и заполняем её синтетическими данными. Всё готово — вы можете работать с синтетической копией так же, как с реальной таблицей.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Интеграция с ClickHouse: почему это важно&lt;/h3&gt;
&lt;p&gt;ClickHouse — популярная колоночная СУБД для аналитики. Генерация синтетических данных прямо в экосистему ClickHouse открывает широкие возможности:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Тестирование производительности&lt;/b&gt; — можно генерировать датасеты любого размера и проверять, как ClickHouse справляется с нагрузкой.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Разработка без доступа к продакшену&lt;/b&gt; — разработчики получают рабочую копию данных без риска утечки конфиденциальной информации.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Обучение моделей&lt;/b&gt; — синтетические данные можно использовать для предварительного обучения ML-моделей, не затрагивая реальные данные.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Альтернативный подход — использование встроенных средств ClickHouse, таких как движок `GenerateRandom`. Однако SDV даёт гораздо более качественные данные, потому что он не просто генерирует случайные значения, а воспроизводит реальные статистические паттерны.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Что дальше: улучшение качества синтеза&lt;/h3&gt;
&lt;p&gt;Если качество синтеза (особенно Column Pair Trends) вас не устраивает, вот несколько способов его улучшить:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Увеличьте объём обучающих данных&lt;/b&gt; — вместо 10 000 строк загрузите 50 000 или 100 000.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Попробуйте CTGANSynthesizer&lt;/b&gt; — нейросетевой синтезатор лучше справляется со сложными зависимостями.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Настройте метаданные вручную&lt;/b&gt; — если автоматическое определение типов сработало неидеально, вы можете отредактировать `metadata.json` и указать типы явно.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Используйте условную генерацию&lt;/b&gt; — SDV позволяет фиксировать значения отдельных колонок и генерировать остальные с учётом этих условий.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-03-v-00.52.49.png" width="1360" height="708" alt="" /&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-09-03-v-00.53.29.png" width="2016" height="666" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Заключение&lt;/h3&gt;
&lt;p&gt;Мы прошли полный путь: от установки библиотек до готовой синтетической таблицы в ClickHouse. SDV оказался мощным и при этом простым в использовании инструментом — весь процесс уместился в один скрипт на 80 строк.&lt;/p&gt;
&lt;p&gt;Главные выводы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;SDV&lt;/b&gt; — это не просто генератор случайных данных, а интеллектуальный инструмент, который сохраняет статистическую структуру оригинала.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`GaussianCopulaSynthesizer`&lt;/b&gt; — отличная точка входа: быстрый, прозрачный, даёт хорошее качество.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Встроенная оценка качества&lt;/b&gt; позволяет объективно понять, насколько синтетика похожа на реальные данные.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Интеграция с ClickHouse&lt;/b&gt; через `clickhouse-connect` делает процесс полностью автоматизированным.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Синтетические данные открывают новые возможности для разработки, тестирования и анализа данных — без рисков, связанных с работой с реальными данными. А SDV даёт в руки инструмент, который превращает эту идею в реальность за считанные минуты.&lt;/p&gt;
&lt;p&gt;ПЫСЫ:&lt;/p&gt;
&lt;p&gt;Можно еще попробовать так: CTGANSynthesizer&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;from sdv.single_table import GaussianCopulaSynthesizer, CTGANSynthesizer&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Но надо будет дольше ждать...  и заменить тип в строке на&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;CTGANSynthesizer&lt;/code&gt;&lt;/pre&gt;&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;uv run sdv_py_v55.py
Загружено 9994 строк
Метаданные сохранены в metadata.json
Начинаем обучение синтезатора...
PerformanceAlert: Using the CTGANSynthesizer on this data is not recommended. To model this data, CTGAN will generate a large number of columns.

Original Column Name   Est # of Columns (CTGAN)
Order Date             1236
Ship Date              1334
Ship Mode              4
Customer Name          793
segment                3
Country/Region         1
region                 4
category               3
Sub-Category           17
Product Name           1849
sales                  5825
quantity               11
discount               12
profit                 7287

We recommend preprocessing discrete columns that can have many values, using 'update_transformers'. Or you may drop columns that are not necessary to model. (Exit this script using ctrl-C)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Все .. комп полетел)) 5 мин... 7 мин... 15... чем то напоминает майнинг))) .... 20... 30... пойду пожалуй спать ... утром все еще майнит, видимо надо другие параметры указывать и разобраться лучше для чего эта опция. Первая же отработала очень быстро.&lt;/p&gt;
</description>
</item>

<item>
<title>Управление доступом в дашбордах с Marimo и OPA: простое решение для сложных политик</title>
<guid isPermaLink="false">345</guid>
<link>https://gavrilov.info/all/upravlenie-dostupom-v-dashbordah-s-marimo-i-opa-prostoe-reshenie/</link>
<pubDate>Fri, 28 Aug 2026 00:14:17 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/upravlenie-dostupom-v-dashbordah-s-marimo-i-opa-prostoe-reshenie/</comments>
<description>
&lt;p&gt;В современном мире данных всё чаще требуется не только предоставлять пользователям интерактивные инструменты для анализа, но и жёстко контролировать, кто и к каким данным может обращаться. Классический подход — встраивать логику доступа прямо в код приложения — быстро становится негибким и трудно поддерживаемым. На помощь приходят специализированные решения: &lt;b&gt;Marimo&lt;/b&gt; для построения дашбордов и &lt;b&gt;OPA&lt;/b&gt; (Open Policy Agent) для централизованного управления политиками доступа.&lt;/p&gt;
&lt;p&gt;В этой статье мы разберём, как написать простое приложение на Marimo, которое проверяет права пользователя через OPA, а затем обсудим, как эта связка может быть расширена на полноценный дашборд, работающий с Trino и управляющий доступом к данным на разных уровнях.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Что такое Marimo и OPA?&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Marimo&lt;/b&gt; (&lt;a href="https://github.com/marimo-team/marimo)"&gt;https://github.com/marimo-team/marimo)&lt;/a&gt; — это современный интерактивный блокнот для Python, который сочетает в себе удобство Jupyter с реактивностью и возможностью превращать блокнот в веб-приложение. В отличие от классических блокнотов, Marimo автоматически пересчитывает ячейки при изменении входных данных, что делает его идеальным для создания дашбордов и инструментов анализа.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;OPA&lt;/b&gt; (Open Policy Agent: &lt;a href="https://www.openpolicyagent.org)"&gt;https://www.openpolicyagent.org)&lt;/a&gt; — это универсальный движок политик с открытым исходным кодом. Он позволяет описывать правила доступа на языке Rego (декларативном, похожем на JSON) и принимать решения на основе входных данных (input). OPA работает как отдельный сервис, принимающий запросы и возвращающий разрешено или запрещено действие. Такой подход отделяет политики от кода приложения, упрощая их изменение, аудит и повторное использование.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2026-08-28-v-00.13.05.png" width="1184" height="1682" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h3&gt;Простой пример: проверка доступа в Marimo&lt;/h3&gt;
&lt;p&gt;Представьте, что у нас есть дашборд, в котором разные пользователи могут видеть разные разделы. Вместо того чтобы хардкодить условия в Python, мы выносим логику в OPA.&lt;/p&gt;
&lt;p&gt;Ниже приведён фрагмент кода на Marimo, который реализует минимальный интерфейс для проверки доступа:&lt;/p&gt;
&lt;p&gt;Запускаем OPA&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;podman run -d --name opa-server -p 8181:8181 openpolicyagent/opa \                
  run --server --addr=0.0.0.0:8181 --log-level debug&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Создаем политику Rego&lt;/p&gt;
&lt;p&gt;nano policy.rego&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;package app.authz
default allow = false
allow if {
    input.user.role == &amp;quot;admin&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Отправляем политику в OPA:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;curl -X PUT --data-binary @policy.rego http://localhost:8181/v1/policies/my_policy&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Далее запускаем новый блокнот Marimo&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mkdir marimo-opa
cd marimo-opa
uv init 
uv add marimo requests
uv run marimo edit app.py&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;а теперь само приложение Marimo&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;import marimo as mo
import requests

# Элементы управления
user_role = mo.ui.dropdown([&amp;quot;user&amp;quot;, &amp;quot;admin&amp;quot;], value=&amp;quot;user&amp;quot;, label=&amp;quot;Роль пользователя:&amp;quot;)
resource = mo.ui.text(value=&amp;quot;dashboard&amp;quot;, label=&amp;quot;Ресурс:&amp;quot;)
submit = mo.ui.button(label=&amp;quot;Проверить доступ&amp;quot;)

mo.hstack([user_role, resource, submit])&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;После нажатия кнопки код отправляет запрос к OPA:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;mo.stop(not submit.value, mo.md(&amp;quot;*Нажмите кнопку для проверки прав*&amp;quot;))

opa_url = &amp;quot;http://localhost:8181/v1/data/app/authz/allow&amp;quot;
payload = {
    &amp;quot;input&amp;quot;: {
        &amp;quot;user&amp;quot;: {&amp;quot;role&amp;quot;: user_role.value},
        &amp;quot;resource&amp;quot;: resource.value
    }
}

try:
    response = requests.post(opa_url, json=payload).json()
    is_allowed = response.get(&amp;quot;result&amp;quot;, False)
    status = mo.md(&amp;quot;**Доступ разрешен**&amp;quot;) if is_allowed else mo.md(&amp;quot;**Доступ запрещен**&amp;quot;)
except Exception as e:
    status = mo.md(f&amp;quot;**Ошибка подключения к ОРА:** {e}&amp;quot;)

status&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Что здесь происходит?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Пользователь выбирает роль (user/admin) и вводит название ресурса.&lt;/li&gt;
&lt;li&gt;При клике на кнопку формируется JSON с полем `input`, содержащим роль и ресурс.&lt;/li&gt;
&lt;li&gt;Этот JSON отправляется в OPA по эндпоинту, который возвращает решение (`result` — true/false).&lt;/li&gt;
&lt;li&gt;На основе результата выводится сообщение о разрешении или запрете.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Этот пример демонстрирует, как легко интегрировать OPA в интерфейс на Marimo. Все политики (например, `admin` может всё, а `user` — только определённые ресурсы) хранятся отдельно в OPA и могут быть изменены без переписывания кода приложения.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Расширяем сценарий: дашборд на Trino с двойным контролем доступа&lt;/h3&gt;
&lt;p&gt;Теперь представим более реальную задачу: мы строим дашборд для аналитики, который выполняет SQL-запросы к &lt;b&gt;Trino&lt;/b&gt; — распределённому движку для работы с большими данными. В Trino доступ к таблицам, схемам и столбцам также можно регулировать через OPA. Таким образом, у нас возникает два уровня авторизации:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Уровень приложения (Marimo)&lt;/b&gt; — определяет, может ли пользователь вообще открыть определённый раздел дашборда или выполнить какое-то действие в интерфейсе.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Уровень данных (Trino)&lt;/b&gt; — контролирует, какие именно данные (таблицы, колонки, строки) пользователь может запрашивать через SQL.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Эти два уровня могут обслуживаться &lt;b&gt;разными экземплярами OPA&lt;/b&gt; или одним, но с разными пакетами политик. Например, в Marimo мы проверяем политику `app/authz/allow`, а в Trino — `trino/authz/allow`. Это даёт гибкость: политики для интерфейса и для данных могут управляться разными командами или обновляться независимо.&lt;/p&gt;
&lt;p&gt;В нашем приложении Marimo после успешной проверки прав на доступ к разделу мы можем формировать SQL-запрос и отправлять его в Trino. При этом Trino, в свою очередь, проверит, имеет ли пользователь право читать запрашиваемые таблицы, используя свой OPA-агент. Если хотя бы один из агентов вернёт отказ, пользователь не получит данные.&lt;/p&gt;
&lt;p&gt;Такая двухуровневая архитектура обеспечивает безопасность «в глубину» и позволяет тонко настраивать политики как на уровне интерфейса, так и на уровне сырых данных.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Управление политиками OPA: взгляд в будущее&lt;/h3&gt;
&lt;p&gt;Настройка и поддержка политик OPA, особенно когда речь идёт о десятках таблиц, ролей и атрибутов, может стать сложной задачей. Требуется не только писать правила на Rego, но и поддерживать актуальность данных о пользователях и ресурсах. Для упрощения этой работы существует проект &lt;b&gt;Moat&lt;/b&gt; (Data Control Plane для Trino и OPA).&lt;/p&gt;
&lt;p&gt;Moat предоставляет: &lt;a href="https://github.com/moat-io/moat"&gt;https://github.com/moat-io/moat&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SCIM2.0-сервер для интеграции с провайдерами идентичности (Okta, EntraId и др.);&lt;/li&gt;
&lt;li&gt;ингестию атрибутов пользователей и групп из различных источников (SQL, LDAP);&lt;/li&gt;
&lt;li&gt;ингестию метаданных о таблицах и представлениях из каталогов данных;&lt;/li&gt;
&lt;li&gt;готовые политики Rego для типовых сценариев (RBAC, ABAC);&lt;/li&gt;
&lt;li&gt;OPA-совместимый Bundle API с кешированием для быстрого обновления политик.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Moat сам не принимает решений в рантайме — он лишь поставляет OPA необходимую информацию (политики и данные). Это позволяет удобно управлять множеством кластеров Trino и эфемерных окружений, добавляя OPA-контейнер в каждый координатор и указывая ему на Moat как источник бандлов.&lt;/p&gt;
&lt;p&gt;Однако подробное рассмотрение Moat выходит за рамки этой статьи. Мы обязательно вернёмся к нему в отдельном материале, где разберём его архитектуру, настройку и примеры использования.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Заключение&lt;/h3&gt;
&lt;p&gt;Связка Marimo и OPA даёт разработчикам дашбордов мощный и гибкий инструмент для управления доступом. Вы можете отделить политики от кода, упростить их изменение и аудит, а также комбинировать несколько OPA-агентов для разных уровней — приложения и данных. В сочетании с Trino и такими инструментами, как Moat, эта экосистема становится полноценным решением для корпоративных аналитических платформ.&lt;/p&gt;
&lt;p&gt;Попробуйте предложенный пример в своём проекте — и вы убедитесь, как легко внедрить централизованное управление доступом, не усложняя код приложения. А о Moat мы расскажем в следующий раз!&lt;/p&gt;
</description>
</item>

<item>
<title>Анатомия невидимости: гид по рекламным идентификаторам (2025+)</title>
<guid isPermaLink="false">312</guid>
<link>https://gavrilov.info/all/anatomiya-nevidimosti-gid-po-reklamnym-identifikatoram-2025/</link>
<pubDate>Tue, 20 Jan 2026 22:16:15 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/anatomiya-nevidimosti-gid-po-reklamnym-identifikatoram-2025/</comments>
<description>
&lt;p&gt;В современном маркетинге данные — это новая нефть, а &lt;b&gt;рекламный идентификатор (Advertising ID)&lt;/b&gt; — это трубопровод, по которому эта нефть течет. От смартфона в кармане до умного телевизора в гостиной: каждое устройство имеет свой цифровой паспорт.&lt;/p&gt;
&lt;p&gt;В этой статье мы разберем не только скрытую механику «рекламной слежки», но и юридические риски для бизнеса в РФ, новые технологии обхода блокировок и то, как клиентский опыт (CX) меняется в эпоху тотальной приватности.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;1. Зоопарк идентификаторов: Кто есть кто&lt;/h3&gt;
&lt;p&gt;Рынок рекламных ID фрагментирован. Каждый сегмент решает одну задачу — узнать пользователя, — но делает это разными способами.&lt;/p&gt;
&lt;h4&gt;📱 Мобильные устройства (MAID — Mobile Advertising IDs)&lt;/h4&gt;
&lt;p&gt;Это самые ценные идентификаторы, так как смартфон является наиболее персональным (“интимным”) устройством.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;IDFA (Identifier for Advertisers):&lt;/b&gt; Стандарт Apple (iOS). После внедрения *App Tracking Transparency (ATT)* в iOS 14.5 доступ к нему закрыт по умолчанию.  &lt;br /&gt;
&gt; &lt;b&gt;Важно:&lt;/b&gt; Лишь 20-30% пользователей в мире нажимают «Разрешить» (Allow Tracking). Это создало огромную «слепую зону» в аналитике.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GAID (Google Advertising ID) / AAID:&lt;/b&gt; Аналог для Android. Позволяет связывать активность пользователя между разными приложениями. Google также движется в сторону ограничения доступа через инициативу Privacy Sandbox on Android.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;📺 Телевизоры и Set-Top Box (CTV IDs)&lt;/h4&gt;
&lt;p&gt;С ростом Smart TV и стримингов маркетологи теперь трекают пользователей «на диване».&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Примеры:&lt;/b&gt; TIFA (Samsung), Roku ID, Amazon Fire TV ID.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Логика Household (Домохозяйство):&lt;/b&gt; В отличие от личных смартфонов, эти ID часто привязаны к семье.
&lt;ul&gt;
  &lt;li&gt;*Инсайт эксперта по данным:* Это создает проблему «шумных данных». Если вы рекламируете женские духи, а телевизор смотрит муж или ребенок, атрибуция будет ошибочной. Для очистки данных используются Cross-Device графы, связывающие TV ID с мобильными телефонами, находящимися в той же Wi-Fi сети.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;🌐 Веб-идентификаторы&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Third-Party Cookies:&lt;/b&gt; Старейший и умирающий стандарт. Текстовые файлы, оставляемые рекламными сетями (не владельцем сайта) в браузере.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Stable IDs / Hashed Emails:&lt;/b&gt; Новая валюта рынка. Это зашифрованные (хэшированные) адреса электронной почты или номера телефонов. Используются в таких решениях, как *Unified ID 2.0*.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;details&gt;&lt;br /&gt;
&lt;summary&gt;&lt;b&gt;🔍 Юридический комментарий: Персональные данные в РФ&lt;/b&gt;&lt;/summary&gt;&lt;/p&gt;
&lt;p&gt;Согласно &lt;b&gt;152-ФЗ «О персональных данных»&lt;/b&gt; &lt;a href="https://normativ.kontur.ru/document?moduleId=1&amp;documentId=501173"&gt;normativ.kontur.ru&lt;/a&gt; и позиции Роскомнадзора, любые данные, которые позволяют (даже косвенно) идентифицировать личность, могут считаться персональными данными (ПДн).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Является ли IDFA/GAID персональными данными?&lt;/b&gt; Формально — нет, это псевдонимизированные данные. &lt;b&gt;НО:&lt;/b&gt; Как только вы обогащаете этот ID номером телефона из вашей CRM или связываете его с профилем конкретного клиента, он становится ПДн.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Риски:&lt;/b&gt; Хранение баз с “просто ID” безопаснее, но как только происходит «склейка» (matching) с реальным человеком, вы обязаны иметь согласие на обработку (и часто — на передачу третьим лицам, т.е. рекламным сетям).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Штрафы:&lt;/b&gt; За нарушение правил обработки ПДн штрафы для юрлиц могут достигать 18 млн рублей (при повторном нарушении при локализации), а за утечки — вплоть до оборотных штрафов (обсуждаемые поправки). Подробнее о сборе данных &lt;a href="https://adesk.ru/blog/kak-biznesu-sobirat-i-khranit-personalnye-dannye-chtoby-ne-poluchit-shtraf/"&gt;adesk.ru&lt;/a&gt;.&lt;br /&gt;
&lt;/details&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;2. Механика: Как они строятся и живут&lt;/h3&gt;
&lt;h4&gt;Формула генерации&lt;/h4&gt;
&lt;p&gt;Большинство мобильных ID (GAID, IDFA) представляют собой &lt;b&gt;UUID (Universally Unique Identifier) версии 4&lt;/b&gt;. Это 128-битное число.&lt;/p&gt;
&lt;p&gt;$$ P(collision) \approx \frac{n^2}{2 \times 2^{128}} $$&lt;/p&gt;
&lt;p&gt;Вероятность совпадения двух таких ID астрономически мала.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Пример:&lt;/b&gt; `123e4567-e89b-12d3-a456-426614174000`&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Генерация:&lt;/b&gt; Алгоритм использует криптографически стойкий генератор случайных чисел (CSPRNG) + энтропию системы (время запуска, «шум» железа).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Жизненный цикл и безопасность&lt;/h4&gt;
&lt;p&gt;Главное отличие рекламного ID от аппаратного (IMEI) — возможность сброса (&lt;b&gt;Resettability&lt;/b&gt;).&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Действие пользователя:&lt;/b&gt; В настройках конфиденциальности нажимается «Сбросить рекламный ID».&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Реакция ОС:&lt;/b&gt; Генерируется новый UUID.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Результат:&lt;/b&gt; Для рекламных сетей устройство становится «чистым листом». История интересов разрывается.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;3. E-commerce: Сквозь экраны к покупке&lt;/h3&gt;
&lt;p&gt;В интернет-коммерции ID — это клей, собирающий разрозненные клики в путь покупателя (Customer Journey Map).&lt;/p&gt;
&lt;h4&gt;Сквозная аналитика (Cross-Device)&lt;/h4&gt;
&lt;p&gt;Как понять, что телефон `User_A` и ноутбук `Cookie_B` — это один человек?&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Deterministic (Точный метод):&lt;/b&gt; «Золотой стандарт». Пользователь залогинился в магазине под своим Email на обоих устройствах. Связка 100% достоверна.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Probabilistic (Вероятностный метод):&lt;/b&gt; Система видит, что телефон и ноутбук ежедневно выходят в сеть с одного IP-адреса Wi-Fi в одно время, имеют похожие паттерны посещения сайтов. Алгоритмы с вероятностью 90%+ «склеивают» профили в один Household.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Механика таргетинга (RTB – Real Time Bidding)&lt;/h4&gt;
&lt;p&gt;Процесс показа рекламы занимает &lt;b&gt;менее 100 миллисекунд&lt;/b&gt;:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Вы смотрите кроссовки в приложении (система фиксирует ваш `GAID`).&lt;/li&gt;
&lt;li&gt;Вы открываете новостной сайт. Сайт отправляет ваш `GAID` на рекламную биржу.&lt;/li&gt;
&lt;li&gt;DSP (платформа закупки) узнает ваш ID в базе сегментов: *«Это тот же, кто смотрел Nike 5 минут назад!»*.&lt;/li&gt;
&lt;li&gt;Происходит мгновенный аукцион, ставка выигрывает, и вам показывается баннер.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;4. Феномен Amazon Ads и Retail Media&lt;/h3&gt;
&lt;p&gt;Amazon (и его аналоги в РФ) стоит особняком. Это закрытая экосистема (&lt;b&gt;Walled Garden&lt;/b&gt;), чья сила не в технологиях трекинга, а в транзакционных данных. Им не нужно *угадывать*, что вы хотите купить, они *знают*, что вы покупаете.&lt;/p&gt;
&lt;h4&gt;Идентификатор Amazon&lt;/h4&gt;
&lt;p&gt;В основе лежит не «летучий» UUID устройства, а &lt;b&gt;Internal Customer ID&lt;/b&gt;, жестко привязанный к аккаунту.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Формула матчинга:&lt;/b&gt; Для обмена данными с внешним миром используется &lt;b&gt;Hashed Email (HEM)&lt;/b&gt;. Ваш email превращается в необратимую строку (обычно SHA-256).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Clean Rooms (AMC):&lt;/b&gt; Amazon Marketing Cloud позволяет крупным брендам загружать свои CRM-данные в защищенную среду, где они пересекаются с данными Amazon. Рекламодатель получает инсайты (например, “Клиенты, купившие кофемашину у нас на сайте, покупают капсулы на Amazon”), но не видит персональных данных конкретных людей.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;5. Война за приватность и обходные пути&lt;/h3&gt;
&lt;p&gt;Индустрия находится в состоянии холодной войны между запросом на приватность и эффективностью.&lt;/p&gt;
&lt;h4&gt;Главные сложности&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Apple ATT:&lt;/b&gt; Обрушение эффективности рекламы Facebook на iOS. Стоимость привлечения клиента (CAC) выросла на 40-60%.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Смерть Cookies:&lt;/b&gt; Google Chrome (хоть и откладывает полное отключение) внедряет Privacy Sandbox, заменяя индивидуальные куки на FLoC/Topics API (группировку по интересам).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Блокировщики:&lt;/b&gt; AdBlock режет запросы к доменам трекеров. (на уровне DNS, например AdGuard)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Как рынок обходит блокировки? Технический Deep Dive&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Server-Side Tracking (S2S / CAPI):&lt;/b&gt;  &lt;br /&gt;
Вместо отправки данных пикселем из браузера (JS), данные о покупке отправляются напрямую с бэкенда магазина на сервер рекламной системы (например, через Facebook Conversions API).&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;Плюс:* Не блокируется AdBlock и браузерами. Точность данных выше.&lt;/li&gt;
  &lt;li&gt;Минус:* Сложная техническая реализация. Требует согласия пользователя на передачу данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;b&gt;Fingerprinting (Серый метод):&lt;/b&gt;  &lt;br /&gt;
Сбор уникальных параметров устройства без использования cookie:&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;`Screen Resolution` + `User Agent` + `Battery Level` + `System Fonts` + `AudioContext`&lt;/li&gt;
  &lt;li&gt;Такой “цифровой отпечаток” уникален для 95% пользователей. Apple и Google активно борются с этим методом, считая его нарушением приватности.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;Итог: Тренды 2025+ и рекомендации&lt;/h3&gt;
&lt;p&gt;Эра «дикого запада», когда можно было незаметно следить за каждым шагом, заканчивается. Мы переходим в эру агрегированных данных и доверительного маркетинга (Zero-Party Data).&lt;/p&gt;
&lt;h4&gt;Ключевые тренды:&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;First-Party Data — король:&lt;/b&gt; Компании, владеющие собственными данными и прямым контактом с клиентом (Email, App), выигрывают. Зависимость от Facebook становится токсичной.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Retail Media Networks:&lt;/b&gt; Бум рекламных сетей маркетплейсов. Они обладают данными о деньгах, а не о кликах.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AI вместо Cookies:&lt;/b&gt; Алгоритмы машинного обучения будут «достраивать» потерянные данные. Например, Google GA4 уже использует моделирование конверсий для пользователей, отказавшихся от трекинга.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;✅ Рекомендация&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Инвестируйте в CDP (Customer Data Platform):&lt;/b&gt; Собирайте все данные (CRM, сайт, приложение) в одном месте.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Внедряйте Server-Side трекинг:&lt;/b&gt; Это единственный способ сохранить точность аналитики в будущем.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Тестируйте новые каналы:&lt;/b&gt; Telegram Ads (работает без кук, на контексте каналов) или Retail Media.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Аудит согласий:&lt;/b&gt; Проверьте формы сбора данных на сайте. Галочка «Согласен на рекламную рассылку» должна быть отделена от «Согласен на обработку ПДн». Но мне, если честно, не нравится такой подход. Я бы сделал так – Типа Посмотри 10 рекламных роликов, и спи спокойно сегодня до 12, больше показывать сегодня не буду типа)))&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Обезличивание:&lt;/b&gt; Используйте методы обезличивания (деперсонализации) при передаче данных партнерам, как того требуют новые правила &lt;a href="https://www.consultant.ru/document/cons_doc_LAW_511607/d3d38cd263a833779d35b1d4892762b85632b1b4/"&gt;consultant.ru&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Цели обработки:&lt;/b&gt; Четко прописывайте цели в политике конфиденциальности (например, не просто “маркетинг”, а “таргетирование рекламы в сетях Яндекса”) &lt;a href="https://rppa.pro/analitika/celi_obrabotki_pdn"&gt;rppa.pro&lt;/a&gt;. Кстати, хороший справочник.&lt;/li&gt;
&lt;/ul&gt;
</description>
</item>

<item>
<title>Обработка логов Trino из Kafka с помощью Vector для удаления полей</title>
<guid isPermaLink="false">295</guid>
<link>https://gavrilov.info/all/obrabotka-logov-trino-iz-kafka-s-pomoschyu-vector-dlya-udaleniya/</link>
<pubDate>Fri, 21 Nov 2025 01:27:16 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/obrabotka-logov-trino-iz-kafka-s-pomoschyu-vector-dlya-udaleniya/</comments>
<description>
&lt;p&gt;В современных архитектурах данных, построенных на Kafka, часто возникает задача обработки или фильтрации потока событий “на лету”. Один из распространенных кейсов — удаление чувствительной информации из логов перед их передачей в следующую систему (например, в SIEM или систему долгосрочного хранения).&lt;/p&gt;
&lt;p&gt;Kafka: &lt;a href="https://hub.docker.com/r/apache/kafka"&gt;https://hub.docker.com/r/apache/kafka&lt;/a&gt;&lt;br /&gt;
Vector: &lt;a href="https://vector.dev/docs"&gt;https://vector.dev/docs&lt;/a&gt;&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-11-21-v-00.28.37.png" width="1662" height="720" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Рассмотрим реальный пример:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Кластер &lt;b&gt;Trino&lt;/b&gt; (или Presto) пишет подробные логи о каждом выполненном запросе в топик Kafka.&lt;/li&gt;
&lt;li&gt;Эти логи содержат как полезные метаданные (пользователь, время, объем данных), так и полную &lt;b&gt;текстовую версию самого SQL-запроса&lt;/b&gt; в поле, например, `query`.&lt;/li&gt;
&lt;li&gt;Задача&lt;b&gt;: Переложить эти логи в другой топик Kafka, но уже &lt;/b&gt;без** поля `query`, чтобы система-подписчик не имела доступа к потенциально конфиденциальной информации в текстах запросов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Для решения этой задачи мы воспользуемся &lt;b&gt;Vector&lt;/b&gt; — легковесным и сверхбыстрым инструментом для обработки данных.&lt;/p&gt;
&lt;h4&gt;План действий&lt;/h4&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Создадим два топика в Kafka: `trino-logs-raw` (для сырых логов) и `trino-logs-cleaned` (для очищенных).&lt;/li&gt;
&lt;li&gt;Настроим Vector для чтения из первого топика, удаления поля `query` и всех служебных метаданных.&lt;/li&gt;
&lt;li&gt;Настроим Vector на запись результата во второй топик.&lt;/li&gt;
&lt;li&gt;Запустим всю цепочку в Docker и протестируем.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Шаг 1: Подготовка Kafka&lt;/h4&gt;
&lt;p&gt;Предполагается, что у вас уже запущен Kafka-брокер в Docker. На основе нашего примера, у вас есть контейнер с именем `broker1`, который является частью Docker-сети `minimal_iceberg_net`.&lt;/p&gt;
&lt;p&gt;Откройте терминал и подключитесь к контейнеру Kafka, чтобы создать топики:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;Создадим сеть 

docker network create my_net 

Запускаем брокер broker:

docker run -d \
  --name broker3 \
  --network=my_net \
  -p 8893:9092 \
  -e KAFKA_NODE_ID=3 \
  -e KAFKA_PROCESS_ROLES='broker,controller' \
  -e KAFKA_CONTROLLER_QUORUM_VOTERS='3@broker3:9093' \
  -e KAFKA_LISTENERS='INTERNAL://0.0.0.0:29092,EXTERNAL://0.0.0.0:9092,CONTROLLER://broker3:9093' \
  -e KAFKA_ADVERTISED_LISTENERS='INTERNAL://broker3:29092,EXTERNAL://localhost:8893' \
  -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP='INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT' \
  -e KAFKA_INTER_BROKER_LISTENER_NAME='INTERNAL' \
  -e KAFKA_CONTROLLER_LISTENER_NAMES='CONTROLLER' \
  -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
  -e KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1 \
  -e KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1 \
  apache/kafka:latest


docker exec --workdir /opt/kafka/bin/ -it broker3 sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Теперь, находясь внутри контейнера, выполните команды:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;# Создаем &amp;quot;сырой&amp;quot; топик для входящих логов Trino
./kafka-topics.sh --create --topic trino-logs-raw --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1

# Создаем &amp;quot;чистый&amp;quot; топик для обработанных логов
./kafka-topics.sh --create --topic trino-logs-cleaned --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;*Обратите внимание: я использую внутренний порт брокера `29092`, который узнали ранее.*&lt;/p&gt;
&lt;p&gt;Выйдите из контейнера командой `exit`.&lt;/p&gt;
&lt;h4&gt;Шаг 2: Конфигурация Vector&lt;/h4&gt;
&lt;p&gt;На вашей локальной машине создайте структуру папок:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;vector-trino-processor/
└── config/
    └── vector.toml&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Поместите в файл `vector.toml` следующую конфигурацию. Это сердце нашего решения.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;# vector-trino-processor/config/vector.toml

# ==================================
#          ИСТОЧНИК ДАННЫХ
# ==================================
# Читаем сырые логи из Kafka
[sources.trino_raw_logs]
  type = &amp;quot;kafka&amp;quot;
  # Подключаемся к брокеру по имени контейнера и внутреннему порту
  bootstrap_servers = &amp;quot;broker3:29092&amp;quot;
  # Указываем, какой топик слушать
  topics = [&amp;quot;trino-logs-raw&amp;quot;]
  group_id = &amp;quot;vector-trino-cleaner&amp;quot;
  # Vector автоматически распарсит входящие сообщения как JSON
  decoding.codec = &amp;quot;json&amp;quot;

# ==================================
#             ТРАНСФОРМАЦИЯ
# ==================================
# Удаляем поле `query` и служебные метаданные Vector
[transforms.clean_trino_log]
  type = &amp;quot;remap&amp;quot;
  # Получаем данные от нашего источника
  inputs = [&amp;quot;trino_raw_logs&amp;quot;]
  # Скрипт на языке Vector Remap Language (VRL)
  source = '''
  # 1. Удаляем чувствительное поле &amp;quot;query&amp;quot; из лога.
  del(.query)

  # 2. Удаляем все служебные поля, которые Vector добавляет
  #    при чтении из Kafka, чтобы на выходе был чистый JSON.
  del(.headers)
  del(.message_key)
  del(.offset)
  del(.partition)
  del(.source_type)
  del(.timestamp)
  del(.topic)
  '''

# ==================================
#           ПРИЕМНИК ДАННЫХ
# ==================================
# Пишем очищенные логи в новый топик Kafka
[sinks.trino_cleaned_logs]
  type = &amp;quot;kafka&amp;quot;
  # Принимаем на вход данные, прошедшие трансформацию
  inputs = [&amp;quot;clean_trino_log&amp;quot;]
  bootstrap_servers = &amp;quot;broker3:29092&amp;quot;
  # Указываем топик для записи
  topic = &amp;quot;trino-logs-cleaned&amp;quot;
  # Кодируем итоговое событие обратно в JSON
  encoding.codec = &amp;quot;json&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Шаг 3: Запуск и Тестирование&lt;/h4&gt;
&lt;p&gt;Нам понадобится три терминала.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;В Терминале №1 — Запустим Vector&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Перейдите в папку `vector-trino-processor` и выполните команду:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;docker run \
  -d \
  --name vector-processor \
  -v &amp;quot;$(pwd)/config:/etc/vector/&amp;quot; \
  --network=my_net \
  --rm \
  timberio/vector:latest-alpine --config /etc/vector/vector.toml&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Эта команда:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Запускает контейнер Vector в фоновом режиме (`-d`).&lt;/li&gt;
&lt;li&gt;Дает ему имя `vector-processor`.&lt;/li&gt;
&lt;li&gt;Монтирует ваш локальный конфиг (`-v`).&lt;/li&gt;
&lt;li&gt;Подключает его к той же сети, что и Kafka (`--network`).&lt;/li&gt;
&lt;li&gt;Явно указывает, какой файл конфигурации использовать (`--config`).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;В Терминале №2 — Симулируем отправку лога Trino&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Запустим интерактивный Kafka-продюсер.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;docker exec --workdir /opt/kafka/bin -it broker3 ./kafka-console-producer.sh --topic trino-logs-raw --bootstrap-server localhost:29092&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Теперь вставьте в этот терминал JSON, имитирующий лог от Trino, и нажмите Enter:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{&amp;quot;user&amp;quot;:&amp;quot;yuriy&amp;quot;,&amp;quot;source&amp;quot;:&amp;quot;trino-cli&amp;quot;,&amp;quot;queryId&amp;quot;:&amp;quot;20231120_123456_00001_abcde&amp;quot;,&amp;quot;query&amp;quot;:&amp;quot;SELECT * FROM sensitive_table a JOIN other_table b ON a.id = b.id WHERE a.credit_card = '1234-5678-9012-3456'&amp;quot;,&amp;quot;state&amp;quot;:&amp;quot;FINISHED&amp;quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;В Терминале №3 — Проверяем результат&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Запустим Kafka-консьюмер, который будет слушать &lt;b&gt;очищенный&lt;/b&gt; топик `trino-logs-cleaned`.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;docker exec --workdir /opt/kafka/bin -it broker3 ./kafka-console-consumer.sh --topic trino-logs-cleaned --bootstrap-server localhost:29092 --from-beginning&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Вы практически мгновенно увидите результат работы Vector — тот же самый лог, но уже &lt;b&gt;без поля `query`&lt;/b&gt;:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;{&amp;quot;user&amp;quot;:&amp;quot;yuriy&amp;quot;,&amp;quot;source&amp;quot;:&amp;quot;trino-cli&amp;quot;,&amp;quot;queryId&amp;quot;:&amp;quot;20231120_123456_00001_abcde&amp;quot;,&amp;quot;state&amp;quot;:&amp;quot;FINISHED&amp;quot;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Мы построили простой, но мощный конвейер для обработки данных в режиме реального времени, решив поставленную задачу с минимальными усилиями.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Snimok-ekrana-2025-11-21-v-01.25.17.png" width="1652" height="470" alt="" /&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>И еще немного про безопасность в масштабе</title>
<guid isPermaLink="false">274</guid>
<link>https://gavrilov.info/all/i-esche-nemnogo-pro-bezopasnost-v-masshtabe/</link>
<pubDate>Fri, 29 Aug 2025 00:02:28 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/i-esche-nemnogo-pro-bezopasnost-v-masshtabe/</comments>
<description>
&lt;h4&gt;Ranger vs. OPA: Битва архитектур... и почему OPAL меняет правила игры&lt;/h4&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;● Ranger has a fixed development model
● To add new systems you need to write new modules,
compile and roll out Ranger
● OPA is all REST
● Basically everything is configuration
● We can build the 80% abstraction layer easily
● Anybody else -&amp;gt; they can build whatever extra they need -&amp;gt; in config!&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В мире современных распределённых систем управление доступом (авторизация) — одна из самых сложных и критически важных задач. Компании постоянно ищут баланс между безопасностью, гибкостью и скоростью разработки. Начальные тезисы были абсолютно точны:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;У Ranger фиксированная модель разработки. Чтобы добавить поддержку новых систем, нужно писать новые модули. [...] OPA полностью построен на REST. По сути, всё является конфигурацией. [...] Мы можем создать 80% абстракции, а остальные сами допишут всё, что нужно, через конфиг!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Это сравнение описывает переход от традиционной, монолитной архитектуры к современной, микросервисной. Однако история неполная без третьего ключевого элемента — OPAL, который решает фундаментальную проблему OPA при масштабировании.&lt;/p&gt;
&lt;p&gt;Давайте рассмотрим все три компонента по порядку.&lt;/p&gt;
&lt;h5&gt;1. “Классический” подход: Apache Ranger&lt;/h5&gt;
&lt;p&gt;Apache Ranger — это зрелая и мощная система для централизованного управления политиками безопасности в экосистеме больших данных (Hadoop, Hive, Kafka и т.д.).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Как это работает:&lt;/b&gt; Ranger работает по принципу “сервер + плагины”. Центральный сервер хранит все политики доступа. В каждую защищаемую систему (например, в Hive) устанавливается специальный плагин, который периодически опрашивает сервер Ranger, скачивает актуальные политики и кэширует их для быстрой проверки доступа.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Сильные стороны:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Централизация:&lt;/b&gt; Единый центр для аудита и управления доступом.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Мощность:&lt;/b&gt; Глубокая интеграция с поддерживаемыми системами (например, безопасность на уровне колонок в Hive).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Слабые стороны (те самые “фиксированные модели разработки”):&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Негибкость:&lt;/b&gt; Поддержка новой системы, не входящей в стандартный набор, требует написания плагина на Java, компиляции и развертывания новой версии Ranger. Это медленно и требует узкой экспертизы.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;“Бутылочное горлышко”:&lt;/b&gt; Все изменения проходят через центральную команду, что замедляет продуктовые команды.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Не для микросервисов:&lt;/b&gt; Этот подход плохо подходит для динамичного мира микросервисов, где новые сервисы появляются каждый день.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Аналогия:&lt;/b&gt; Ranger — это как служба безопасности крупного завода, которая работает только со стандартными станками этого завода. Если вы покупаете новый станок из-за границы, вам нужно написать для службы безопасности целую новую инструкцию и переобучить персонал.&lt;/p&gt;
&lt;h5&gt;2. “Гибкий” подход: Open Policy Agent (OPA)&lt;/h5&gt;
&lt;p&gt;OPA — это универсальный движок политик с открытым исходным кодом. Его философия прямо противоположна Ranger. OPA ничего не знает о тех, кого он защищает.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Как это работает:&lt;/b&gt;
&lt;ol start="1"&gt;
  &lt;li&gt;Ваш сервис, получив запрос, формирует JSON-документ с контекстом (`{“user”: “alice”, “action”: “read”, “resource”: “document”}`).&lt;/li&gt;
  &lt;li&gt;Он отправляет этот JSON в OPA через простой REST API-вызов.&lt;/li&gt;
  &lt;li&gt;OPA применяет к этому JSON’у правила, написанные на языке &lt;b&gt;Rego&lt;/b&gt;, и мгновенно возвращает решение: `allow` или `deny`.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Сильные стороны:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Универсальность:&lt;/b&gt; OPA может управлять доступом к чему угодно — микросервисам, Kubernetes, конвейерам CI/CD, базам данных.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Policy-as-Code:&lt;/b&gt; Политики на Rego — это код. Их можно хранить в Git, версионировать, тестировать и автоматически развертывать.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Децентрализация:&lt;/b&gt; OPA обычно развертывается как “сайдкар”-контейнер рядом с каждым экземпляром сервиса, что обеспечивает низкую задержку и высокую отказоустойчивость.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Проблема, которую OPA создает:&lt;/b&gt;  &lt;br /&gt;
Представьте, у вас 500 микросервисов, и рядом с каждым работает свой экземпляр OPA. Возникают вопросы:&lt;/li&gt;

&lt;ul&gt;
  &lt;li&gt;Как доставить обновление политики во все 500 экземпляров OPA одновременно?&lt;/li&gt;
  &lt;li&gt;Откуда OPA возьмет данные для принятия решений (например, список ролей пользователя или владельцев документа)? Если каждый из 500 экземпляров OPA будет сам ходить в базу данных, это создаст колоссальную нагрузку.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Здесь на сцену выходит OPAL.&lt;/p&gt;
&lt;h5&gt;3. “Связующее звено”: OPAL (Open Policy Administration Layer)&lt;/h5&gt;
&lt;p&gt;OPAL — это не еще один движок политик. Это &lt;b&gt;административный слой реального времени для OPA&lt;/b&gt;. Его единственная задача — поддерживать политики и данные в ваших OPA-агентах в актуальном состоянии.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/image-210.png" width="1997" height="945" alt="" /&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Как это работает (OPA + OPAL):**
&lt;ol start="1"&gt;
  &lt;li&gt;Политики (Rego-файлы) хранятся в Git-репозитории. Данные (роли, атрибуты) — в базах данных или API.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;OPAL Server&lt;/b&gt; подписывается на изменения в этих источниках (например, через веб-хуки из Git или топики Kafka).&lt;/li&gt;
  &lt;li&gt;Когда происходит изменение (например, разработчик пушит новую политику в Git), OPAL Server получает уведомление.&lt;/li&gt;
  &lt;li&gt;Сервер немедленно публикует сообщение об обновлении в легковесный канал (pub/sub, обычно через WebSockets).&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;OPAL Clients&lt;/b&gt;, работающие рядом с каждым OPA, получают это сообщение.&lt;/li&gt;
  &lt;li&gt;Клиенты сами скачивают нужные обновления (новую политику из Git, свежие данные из БД) и загружают их в свой локальный OPA.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Что это дает:&lt;/b&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Обновления в реальном времени:&lt;/b&gt; Изменение политики в Git моментально распространяется по всей системе.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Событийная архитектура:&lt;/b&gt; Нет необходимости постоянно опрашивать источники. Это очень эффективно.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Полное разделение:&lt;/b&gt; OPA отвечает только за принятие решений. OPAL — за доставку “знаний” для этих решений.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Масштабируемость:&lt;/b&gt; Эта архитектура легко управляет тысячами OPA-агентов, решая проблему синхронизации.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Завершение истории GitOps:&lt;/b&gt; Вы управляете доступом ко всей вашей инфраструктуре через `git push`, что полностью соответствует исходному тезису: &lt;b&gt;“всё является конфигурацией”&lt;/b&gt;. &lt;a href="https://medium.com/@piyushraw12/building-enterprise-grade-authorization-with-opal-and-opa-decentralized-policy-management-7bddb315433a"&gt;medium.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/telegram-cloud-photo-size-4-5995580363474319391-y.jpg" width="1200" height="1167" alt="" /&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;h4&gt;Итоговое сравнение&lt;/h4&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Критерий&lt;/td&gt;
&lt;td style="text-align: center"&gt;Apache Ranger&lt;/td&gt;
&lt;td style="text-align: center"&gt;OPA (самостоятельно)&lt;/td&gt;
&lt;td style="text-align: center"&gt;OPA + OPAL (Современный стек)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Архитектура&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Монолитный сервер + плагины&lt;/td&gt;
&lt;td style="text-align: center"&gt;Децентрализованный движок политик&lt;/td&gt;
&lt;td style="text-align: center"&gt;Децентрализованный движок + слой управления реального времени&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Процесс обновления&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Код -&gt; Компиляция -&gt; Развертывание&lt;/td&gt;
&lt;td style="text-align: center"&gt;Ручная загрузка политик через API&lt;/td&gt;
&lt;td style="text-align: center"&gt;`git push` -&gt; Автоматическое распространение&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Гибкость&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Низкая (только для поддерживаемых систем)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Очень высокая (универсальный)&lt;/td&gt;
&lt;td style="text-align: center"&gt;Очень высокая + управляемость в масштабе&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Управление данными&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Встроено&lt;/td&gt;
&lt;td style="text-align: center"&gt;Требует самостоятельного решения&lt;/td&gt;
&lt;td style="text-align: center"&gt;Встроено в архитектуру (OPAL следит за данными)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Масштабируемость&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Масштабируется, но обновления медленные&lt;/td&gt;
&lt;td style="text-align: center"&gt;Плохо масштабируется с точки зрения управления&lt;/td&gt;
&lt;td style="text-align: center"&gt;Отлично масштабируется&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Подход&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Классический, централизованный&lt;/td&gt;
&lt;td style="text-align: center"&gt;`Policy-as-Code`, но неполный&lt;/td&gt;
&lt;td style="text-align: center"&gt;`Policy-as-Code` + `GitOps`, событийно-ориентированный&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Вывод&lt;/h4&gt;
&lt;p&gt;Возвращаясь к исходным тезисам, становится ясно, что их автор описывал &lt;b&gt;потенциал OPA&lt;/b&gt;. Однако чтобы этот потенциал раскрылся в крупной организации, необходима система, которая возьмет на себя рутинную, но критически важную работу по синхронизации.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Ranger&lt;/b&gt; — это мощный, но неповоротливый инструмент из прошлого, идеальный для статичных, гомогенных сред.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OPA&lt;/b&gt; — это гениально простой и гибкий движок, сердце современной авторизации.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OPAL&lt;/b&gt; — это нервная система, которая соединяет это сердце с “мозгом” (Git, базы данных) и позволяет всему организму (вашим микросервисам) реагировать на изменения мгновенно.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Современный, масштабируемый и по-настоящему гибкий “слой абстракции”, о котором говорилось в начале, строится именно на связке &lt;b&gt;OPA + OPAL&lt;/b&gt;. Это позволяет создавать платформу, ценность которой, как и было сказано, “заключается в способности объединять внешние инструменты, команды, данные и процессы”.&lt;/p&gt;
&lt;p&gt;Еще было это: &lt;a href="https://gavrilov.info/all/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac/"&gt;https://gavrilov.info/all/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac/&lt;/a&gt;&lt;/p&gt;
</description>
</item>

<item>
<title>Эволюция управления доступом: OPA\OPAL vs FGA, RBAC, ReBAC</title>
<guid isPermaLink="false">271</guid>
<link>https://gavrilov.info/all/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac/</link>
<pubDate>Tue, 19 Aug 2025 23:44:00 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac/</comments>
<description>
&lt;p&gt;В разработке программного обеспечения управление доступом пользователей — одна из критически важных задач. От того, кто и какие действия может выполнять в приложении, напрямую зависит его безопасность, функциональность и надежность. Исторически логика авторизации часто была разбросана по всему коду приложения, что приводило к появлению архитектурного антипаттерна, известного как &lt;b&gt;«Большой ком грязи» (Big Ball of Mud)&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Что такое «Большой ком грязи»?&lt;/b&gt; Это система, в которой отсутствует четкая архитектура. Логика авторизации, выраженная в бесконечных `if-else` конструкциях, смешивается с бизнес-логикой, обработкой данных и представлением. Такую систему практически невозможно поддерживать, аудировать и масштабировать. Любое изменение в правах доступа требует переписывания кода в разных местах, что увеличивает риск ошибок и уязвимостей.&lt;/p&gt;
&lt;p&gt;Современный подход заключается в отделении логики авторизации от основного кода приложения с помощью специализированных инструментов — &lt;b&gt;механизмов политик (Policy Engines)&lt;/b&gt;. Эти системы позволяют централизованно определять, управлять и применять правила доступа. В предоставленном материале рассматриваются три ведущих механизма: &lt;b&gt;OPA (Open Policy Agent)&lt;/b&gt;, &lt;b&gt;OpenFGA&lt;/b&gt; и &lt;b&gt;AWS Cedar&lt;/b&gt;.&lt;/p&gt;
&lt;h5&gt;Основной подход: Политика как код vs. Политика как данные&lt;/h5&gt;
&lt;p&gt;Ключевое различие между механизмами политик заключается в их подходе к определению правил. Это разделение можно описать как «управляемые политикой» (policy-driven) и «управляемые данными» data-driven &lt;a href="https://www.permit.io/blog/policy-engine-showdown-opa-vs-openfga-vs-cedar."&gt;https://www.permit.io/blog/policy-engine-showdown-opa-vs-openfga-vs-cedar.&lt;/a&gt;&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;&lt;b&gt;Управляемые политикой (Policy-Driven)&lt;/b&gt;  &lt;br /&gt;
В этой модели основная логика авторизации описывается в виде кода на специальном декларативном языке. Данные, такие как атрибуты пользователя или ресурса, передаются в механизм во время запроса для принятия решения.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Cedar (AWS):&lt;/b&gt; Яркий пример такого подхода. Cedar делает акцент на читаемости и безопасности политик. Политики пишутся так, чтобы их было легко понять и верифицировать. Joy Scharmen из StrongDM отмечает: «Cedar очень ориентирован на политики. Данные проходят через систему как эфемерный ввод, не требуя предопределенной модели данных» &lt;a href="https://www.permit.io/blog/policy-engine-showdown-opa-vs-openfga-vs-cedar."&gt;https://www.permit.io/blog/policy-engine-showdown-opa-vs-openfga-vs-cedar.&lt;/a&gt; Это идеально для систем, где важна предсказуемость и простота аудита.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;&lt;b&gt;Управляемые данными (Data-Driven)&lt;/b&gt;  &lt;br /&gt;
Здесь ядром системы являются данные, описывающие *отношения* между субъектами (пользователями) и объектами (ресурсами). Политика — это, по сути, модель, которая интерпретирует эти отношения.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;OpenFGA (на основе Google Zanzibar):&lt;/b&gt; Этот механизм реализует модель &lt;b&gt;управления доступом на основе отношений (ReBAC)&lt;/b&gt;. Вы определяете модель (например, «владелец документа может его удалить»), а конкретные связи («пользователь `Alice` является владельцем `document:123`») хранятся как данные &lt;a href="https://www.permit.io/blog/opa-cedar-openfga-why-are-policy-languages-trending."&gt;https://www.permit.io/blog/opa-cedar-openfga-why-are-policy-languages-trending.&lt;/a&gt; Этот подход чрезвычайно масштабируем для систем со сложными иерархиями и связями, как в Google Docs или социальных сетях.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;&lt;b&gt;Гибридный подход&lt;/b&gt;  &lt;br /&gt;
Некоторые механизмы поддерживают оба подхода.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;OPA (Open Policy Agent):&lt;/b&gt; OPA является универсальным механизмом общего назначения &lt;a href="https://www.permit.io/blog/policy-engines."&gt;https://www.permit.io/blog/policy-engines.&lt;/a&gt; Он позволяет как загружать данные и политики в виде «пакетов» (bundles), так и получать их динамически во время выполнения. Это дает максимальную гибкость, но требует более тщательного проектирования архитектуры.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Архитектурные модели развертывания&lt;/h5&gt;
&lt;p&gt;Выбор между централизованной и децентрализованной архитектурой напрямую влияет на производительность и отказоустойчивость.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Централизованная модель:&lt;/b&gt; Все сервисы обращаются к единому центральному сервису авторизации.
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Единый источник правды, консистентность решений.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Может стать узким местом (bottleneck) и единой точкой отказа.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Децентрализованная модель:&lt;/b&gt; Механизм политик разворачивается как «сайдкар» (sidecar) рядом с каждым экземпляром приложения.
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Плюсы:&lt;/b&gt; Минимальная задержка (latency), высокая отказоустойчивость.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Минусы:&lt;/b&gt; Требует синхронизации политик и данных между всеми экземплярами.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Гибридная модель:&lt;/b&gt; «Управляй централизованно, авторизуй локально». Политики и данные управляются из центра, но доставляются на децентрализованные механизмы для локального принятия решений.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Для решения проблемы синхронизации в децентрализованных моделях существуют инструменты, такие как &lt;b&gt;OPAL (Open Policy Administration Layer)&lt;/b&gt;. OPAL работает поверх OPA, Cedar и OpenFGA, обнаруживая изменения в политиках и данных в реальном времени и доставляя обновления агентам &lt;a href="https://docs.opal.ac."&gt;https://docs.opal.ac.&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;Сравнение механизмов: плюсы и минусы&lt;/h5&gt;
&lt;table cellpadding="0" cellspacing="0" border="0" class="e2-text-table"&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Механизм&lt;/td&gt;
&lt;td style="text-align: center"&gt;Описание&lt;/td&gt;
&lt;td style="text-align: center"&gt;Плюсы&lt;/td&gt;
&lt;td style="text-align: center"&gt;Минусы&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;:---&lt;/td&gt;
&lt;td style="text-align: center"&gt;:---&lt;/td&gt;
&lt;td style="text-align: center"&gt;:---&lt;/td&gt;
&lt;td style="text-align: center"&gt;:---&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;OPA (Open Policy Agent)&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Универсальный механизм общего назначения, использующий язык &lt;b&gt;Rego&lt;/b&gt;.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Гибкость:&lt;/b&gt; Поддерживает RBAC, ABAC, ReBAC. Может использоваться не только для авторизации.&lt;br&gt;&lt;b&gt;Экосистема:&lt;/b&gt; Зрелый проект CNCF с огромным сообществом и инструментарием.&lt;br&gt;&lt;b&gt;Адаптивность:&lt;/b&gt; Может работать в stateful и stateless режимах, быть централизованным или децентрализованным.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Сложность:&lt;/b&gt; Язык Rego имеет порог вхождения.&lt;br&gt;&lt;b&gt;Требует дисциплины:&lt;/b&gt; Гибкость может привести к усложнению, если не планировать архитектуру тщательно.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;OpenFGA&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Специализированный механизм, основанный на Google Zanzibar. Реализует &lt;b&gt;ReBAC&lt;/b&gt;.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Масштабируемость:&lt;/b&gt; Идеален для систем с большим количеством пользователей и сложными отношениями между объектами.&lt;br&gt;&lt;b&gt;Производительность:&lt;/b&gt; Проверенная модель, оптимизированная для быстрых проверок разрешений.&lt;br&gt;&lt;b&gt;Четкая модель:&lt;/b&gt; Фокусируется на одной задаче и делает ее хорошо.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Узкая специализация:&lt;/b&gt; Менее интуитивен для простых сценариев RBAC или ABAC &lt;a href="https://www.permit.io/blog/opa-cedar-openfga-why-are-policy-languages-trending"&gt;https://www.permit.io/blog/opa-cedar-openfga-why-are-policy-languages-trending&lt;/a&gt;&lt;br&gt;&lt;b&gt;Синхронизация данных:&lt;/b&gt; Основная сложность — поддерживать граф отношений в актуальном состоянии.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;AWS Cedar&lt;/b&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Механизм, ориентированный на безопасность, читаемость и формальную верификацию политик.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Простота и читаемость:&lt;/b&gt; Политики легко писать и аудировать.&lt;br&gt;&lt;b&gt;Безопасность:&lt;/b&gt; Встроенные средства верификации для проверки корректности политик.&lt;br&gt;&lt;b&gt;Низкий порог вхождения:&lt;/b&gt; Интуитивно понятен для команд, новых в этой области.&lt;/td&gt;
&lt;td style="text-align: center"&gt;&lt;b&gt;Ограниченная гибкость:&lt;/b&gt; В первую очередь предназначен для авторизации и менее гибок, чем OPA.&lt;br&gt;&lt;b&gt;Stateless-ориентированность:&lt;/b&gt; Модель, где все данные передаются с запросом, может не подходить для всех сценариев.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h5&gt;Итог: нет “победителя”, есть правильный инструмент&lt;/h5&gt;
&lt;p&gt;Как было подчеркнуто в дискуссии на KubeCon, «победителя нет». Выбор механизма политик полностью зависит от конкретного случая использования:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Если у вас сложная система с множеством взаимосвязанных разрешений&lt;/b&gt; (например, совместное редактирование документов, социальная сеть), &lt;b&gt;OpenFGA&lt;/b&gt; — ваш выбор.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Если вам нужен универсальный инструмент&lt;/b&gt; для управления политиками в разных частях стека (Kubernetes, CI/CD, микросервисы) и ваша команда готова изучить новый язык, &lt;b&gt;OPA&lt;/b&gt; предоставит максимальную гибкость.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Если ваша главная цель — простая, безопасная и легко проверяемая авторизация&lt;/b&gt; в приложении, и вы цените читаемость политик, &lt;b&gt;Cedar&lt;/b&gt; будет отличным стартом.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Переход от «большого кома грязи» к внешним механизмам политик — это шаг к созданию более надежных, безопасных и поддерживаемых систем. Благодаря таким проектам, как OPA, OpenFGA, Cedar и инструментам вроде OPAL, разработчики получают мощные средства для построения современных систем управления доступом &lt;a href="https://www.permit.io/blog/introduction-to-opal"&gt;https://www.permit.io/blog/introduction-to-opal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OPA + OPAL == 💜&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac.png" width="2152" height="1156" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/permitio/opal?tab=readme-ov-file"&gt;https://github.com/permitio/opal?tab=readme-ov-file&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Спойлер ...&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://gavrilov.info/pictures/Screenshot-from-2025-08-22-12-22-33.png" width="1047" height="252" alt="" /&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>Платформа защиты данных: принципы и практика</title>
<guid isPermaLink="false">130</guid>
<link>https://gavrilov.info/all/platforma-zaschity-dannyh-principy-i-praktika/</link>
<pubDate>Sun, 09 Jun 2024 23:46:23 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/platforma-zaschity-dannyh-principy-i-praktika/</comments>
<description>
&lt;p&gt;Перевод: &lt;a href="https://sanjmo.medium.com/drowning-in-data-a-data-security-platform-dsp-is-your-life-raft-92be7cdc9e66"&gt;https://sanjmo.medium.com/drowning-in-data-a-data-security-platform-dsp-is-your-life-raft-92be7cdc9e66&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;В январе 2024 года Gartner опубликовал свой первый рыночный гид по платформам защиты данных, признав растущую важность объединения контролей безопасности данных, бизнес-логики и детализированной авторизации. Эти ключевые черты позволяют бизнесу раскрыть потенциал всех своих информационных активов и использовать их для принятия решений.&lt;/p&gt;
&lt;p&gt;Защита данных не является новым открытием, а давно признанной необходимостью. В прошлом эти меры внедрялись как второстепенные и изолированные, что затрудняло своевременный и безопасный доступ к корпоративным данным. Однако сейчас организации делают защиту данных приоритетом и внедряют её структурированным образом. Неудивительно, что Gartner сообщает о 70-процентном росте звонков, связанных с защитой данных, между 2021 и 2022 годами.&lt;/p&gt;
&lt;p&gt;Хотя ChatGPT открыл потенциал ИИ, трансформируя наши организации, впереди еще большая возможность в виде персонализированной ИИ-стека. Этот стек объединяет крупные языковые модели и корпоративные данные, позволяя получать результаты, основанные на реальной бизнес-информации.&lt;/p&gt;
&lt;p&gt;С этой мощью компании могут действительно использовать скрытый потенциал огромных объемов структурированных и неструктурированных данных. И, базируя результаты на тщательно отобранных корпоративных данных, они могут уменьшить количество неправильных выводов и повысить доверие к результатам генеративной работы ИИ.&lt;/p&gt;
&lt;p&gt;Однако для достижения этого состояния просветления необходимо сначала убедиться, что соблюдены корпоративные правила безопасности и все соответствующие нормативные требования. Это требует сложной платформы защиты данных (DSP).&lt;/p&gt;
&lt;p&gt;Компоненты платформы защиты данных (DSP)&lt;br /&gt;
Как тормоза у автомобиля, защита данных предназначена не для замедления, а для безопасного ускорения с доверием и уверенностью. Они созданы, чтобы предотвращать как намеренное, так и случайное использование инфраструктуры данных. Цель состоит в том, чтобы обеспечить доступ к нужным данным для нужных людей в нужное время, чтобы принимать бизнес-решения и получать конкурентное преимущество.&lt;/p&gt;
&lt;p&gt;Надежная платформа защиты данных состоит из трёх основных элементов, приведённых ниже.&lt;/p&gt;
&lt;p&gt;Элементы платформы защиты данных (DSP)&lt;br /&gt;
Обнаружение и наблюдение&lt;br /&gt;
Первая итерация больших данных, начатая Hadoop, превратила озера данных в болота данных из-за недостаточного понимания данных. В стремлении сделать данные доступными для анализа был пропущен критический этап их понимания, включая чувствительные данные.&lt;/p&gt;
&lt;p&gt;Современная DSP должна иметь возможность подключаться к исходным системам и определять характер данных. Чувствительность данных скрыта в контексте самих данных. Когда чувствительные данные обнаружены, их необходимо пометить в соответствии с корпоративными правилами безопасности и применимыми нормативными требованиями. Эти данные могут включать личную идентификационную информацию (PII), личную медицинскую информацию (PHI), финансовые данные, интеллектуальную собственность или производственные секреты.&lt;/p&gt;
&lt;p&gt;Ваша DSP должна уметь подключаться ко всем соответствующим источникам данных и выявлять чувствительные данные, используя несколько подходов:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Профилирование исходных данных: сканирование и профилирование данных часто использует выборку, но должно иметь возможность сканировать полный набор данных. Однако это может создать нагрузку на операционные системы. Этот вариант требует разрешений для доступа к исходным данным.&lt;/li&gt;
&lt;li&gt;Профилирование ответов: чтобы преодолеть некоторые из вышеупомянутых барьеров, можно профилировать и классифицировать ответы. Например, можно выявлять электронные письма, номера социального страхования и другую личную информацию.&lt;/li&gt;
&lt;li&gt;Пометка данных может быть ручной, однако чаще всего используется сложные алгоритмы машинного обучения. Этот процесс должен быть непрерывным, так как данные меняются в реальном времени. Таким образом, в вашей DSP необходимы возможности наблюдения.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Определение политики&lt;br /&gt;
Следующий шаг – возможность определения детализированных политик и правил по защите данных, таких как авторизация и шифрование. Ответственные за данные должны иметь возможность интуитивно и с самообслуживанием создавать политики управления, а не использовать старые подходы, распространенные в системах управления идентификацией и доступом. Наиболее распространенный подход – использование интерфейса с выпадающими опциями. Например, могут быть опции для шифрования или маскирования данных или тегов.&lt;/p&gt;
&lt;p&gt;Новые системы позволяют автоматически определять и находить политики. Автоматизация создания политик также помогает, когда пользователь уходит из компании и все соответствующие политики должны быть удалены. Для достижения этой способности важно, чтобы DSP интегрировалась с остальной инфраструктурой управления данными, такой как каталоги данных. Например, интеграция с каталогом данных позволяет пользователям находить данные, видеть, что доступно, запрашивать доступ, фиксировать намерения и согласие, а затем предоставлять доступ. Эти продукты должны сохранять историю доступа и журналы аудита.&lt;/p&gt;
&lt;p&gt;Принуждение к соблюдению политики&lt;br /&gt;
Заключительный этап – это выполнение политик безопасности данных с минимальными накладными расходами и задержками. Для назначения прав доступа в зависимости от роли пользователя в проекте следует использовать контроль доступа на основе ролей (RBAC). Для предоставления доступа на основе комбинации атрибутов пользователя, атрибутов данных и атрибутов окружения следует использовать контроль доступа на основе атрибутов (ABAC), обеспечивая более детализированный контроль.&lt;/p&gt;
&lt;p&gt;Некоторые важные факторы при исполнении политики включают:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Согласованность: политики безопасности должны применяться к данным независимо от того, где они хранятся – в облачных хранилищах данных, операционных системах, хранилищах объектов или озерах данных.&lt;/li&gt;
&lt;li&gt;Низкую задержку и масштабируемость: накладные расходы на безопасность данных должны быть минимальными для запросов. Они также должны масштабироваться с ростом нагрузки.&lt;/li&gt;
&lt;li&gt;Динамичность: предпочтительнее ABAC, так как он динамический и адаптируется с изменением окружения пользователя.&lt;/li&gt;
&lt;li&gt;Адаптивность: продукт для защиты данных должен быть прозрачным для конечных пользователей. В идеале пользователь должен обращаться к конечной точке или использовать API, который автоматически применяет политики безопасности и не требует изменений в схеме или запросах.&lt;/li&gt;
&lt;li&gt;Развертывание: современные продукты безопасности развёртываются либо как SaaS-инструменты, либо в частных облаках, управляемых с помощью Kubernetes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Бесшовное принуждение к соблюдению политики помогает построить доверие к данным и увеличить их полезность. Это позволяет организациям расширять возможности обмена данными с потребителями, такими как развертывание маркетплейсов данных.&lt;/p&gt;
</description>
</item>

<item>
<title>Как хакеры ломают кошельки: шесть главных уязвимостей</title>
<guid isPermaLink="false">61</guid>
<link>https://gavrilov.info/all/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostey/</link>
<pubDate>Thu, 10 Aug 2023 21:10:23 +0300</pubDate>
<author></author>
<comments>https://gavrilov.info/all/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostey/</comments>
<description>
&lt;p&gt;Оригинал статьи тут: &lt;a href="https://forklog.com/exclusive/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostej"&gt;https://forklog.com/exclusive/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostej&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Приватный ключ в большинстве блокчейнов представляет собой строку из 256 бит: на подбор такого пароля к конкретному адресу уйдут миллионы лет работы современных компьютеров.&lt;/p&gt;
&lt;p&gt;Однако криптокошельки все же уязвимы к хакерским атакам — из-за багов в приложениях и ошибок пользователей. Рассказываем о шести способах взлома и объясняем, как обезопасить средства от кражи.&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Weak Address — уязвимые ключи&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Из-за бага в генераторе случайных чисел (ГСЧ) кошелек может создать приватный ключ лишь с несколькими случайными байтами. В идеале приложение работает так:&lt;/p&gt;
&lt;p&gt;Генерирует случайное число заданной длины.&lt;br /&gt;
Преобразует его в короткий формат ключа соответствующего блокчейна.&lt;br /&gt;
Генерирует публичный адрес из ключа.&lt;br /&gt;
В этом случае число fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364110 преобразуется в ключ 5Km2kuu7vtFDPpxywn4u3NLpbr5jKpTB3jsuDU2KYEqeoQJAair, который управляет адресом 1CaZUpjd7VmsyWDFrk9WG9nTYMLcLLvvCw.&lt;/p&gt;
&lt;p&gt;Но иногда ГСЧ допускает ошибку и генерирует строку с большим количеством нулей вроде 0000000000000000000000000000000000000000ffa3cafff0000000000000000 вместо действительно случайного числа. Хакеры называют такие кошельки Weak Addresses.&lt;/p&gt;
&lt;p&gt;Злоумышленники создают ботов. Их алгоритмы регулярно проверяют балансы слабых адресов в сетях биткоина и Ethereum. Если пользователь генерирует такой адрес и отправляет на него криптовалюту, бот сразу же ее ворует.&lt;/p&gt;
&lt;p&gt;Как защититься: после создания кошелька проверьте, действительно ли символы в нем случайны. Используйте инструменты с открытым исходным кодом вроде Swippcore для конвертации ключа короткого формата в длинный на локальной машине.&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Random Vulnerability — извлечение приватных ключей из транзакций&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Биткоины существуют в виде UTXO — неиспользованных выходов. При отправке средств кошелек собирает их на нужную сумму и подписывает транзакцию комбинацией приватного ключа и случайного числа — nonce.&lt;/p&gt;
&lt;p&gt;Из-за бага ГСЧ приложение может подписать разные операции одинаковыми nonce. Если злоумышленники сопоставят и дешифруют подписи таких транзакций, то смогут извлечь приватные ключи.&lt;/p&gt;
&lt;p&gt;Этот метод называется Random Vulnerability. С его помощью хакеры взломали более двух тысяч кошельков на сумму 484 BTC.&lt;/p&gt;
&lt;p&gt;Согласно исследованию компании Kudelski Security, уязвимость также встречается в кошельках Ethereum и EVM-совместимых сетей.&lt;/p&gt;
&lt;p&gt;Как защититься: вовремя обновлять приложения кошельков, в том числе Bitcoin Core и его аналоги для других блокчейнов.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Weak Brainwallet — генерация ключей  из неслучайных данных&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Brainwallet — способ создания приватного ключа на базе пользовательской фразы вместо случайного числа. Ее легко можно запомнить, а значит буквально «хранить в голове».&lt;/p&gt;
&lt;p&gt;Зачастую пользователи генерируют ключи из единичных слов, очевидных комбинаций вроде 12341234, телефонных номеров или цитат из фильмов. Хакеры пользуются человеческой предсказуемостью: они создают ключи из популярных или утекших паролей, а затем выводят криптовалюты с соответствующих кошельков. Таким образом с 2009 года злоумышленники взломали более 19 000 биткоин-кошельков и украли как минимум 4000 BTC.&lt;/p&gt;
&lt;p&gt;Как хакеры ломают кошельки: шесть главных уязвимостей&lt;br /&gt;
Примеры взломанных кошельков, владельцы которых сгенерировали ключи из распространенных фраз. Данные: Privatekeys.&lt;br /&gt;
Как защититься: не использовать Brainwallet, в крайнем случае — придумать действительно сложный пароль из строчных и заглавных букв, цифр и спецсимволов.&lt;/p&gt;
&lt;p&gt;Рассылки ForkLog: держите руку на пульсе биткоин-индустрии!&lt;/p&gt;
&lt;p&gt;Итоги недели&lt;/p&gt;
&lt;p&gt;Итоги недели + главные новости по будням&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Фишинг — пользователь сам отдает ключ&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;С технической точки зрения самый простой способ получить доступ к кошельку — убедить владельца отправить вам ключ. Для этого злоумышленники представляются сотрудниками службы поддержки бирж и кошельков, известными личностями или специалистами по безопасности.&lt;/p&gt;
&lt;p&gt;Например, в феврале 2023 года хакеры отправляли пользователям Trezor фейковые письма от лица компании, в которых сообщали о взломе программного обеспечения кошельков и просили передать сид-фразу для «проверки».&lt;/p&gt;
&lt;p&gt;Кроме того, злоумышленники используют инструменты ончейн-аналитики атак на кошельки биткоин-китов — известных личностей, менеджеров блокчейн-проектов и криптоинфлюэнсеров. Они пишут персонализированные письма и связываются с жертвами по личным каналам коммуникаций.&lt;/p&gt;
&lt;p&gt;Как защититься: ни в коем случае не отправлять приватный ключ или сид-фразу кому бы то ни было.&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Ключи в публичном доступе — мониторинг GitHub&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Разработчики блокчейн-приложений и смарт-контрактов иногда используют личные кошельки для проверки работоспособности кода. Они могут случайно оставить ключи в файлах при публикации проектов на хостинговых сервисах.&lt;/p&gt;
&lt;p&gt;Хакеры отслеживают обновления и загрузки репозиториев на GitHub, Pastebin и других популярных платформах для хранения текстовых заметок. Они проверяют строки, которые начинаются с «5» (биткоин-ключи в формате WIF), содержат слова из словаря сид-фраз или совпадают с длиной закрытого ключа.&lt;/p&gt;
&lt;p&gt;Как защититься: не хранить пароли на компьютере в незашифрованных файлах, не использовать личный кошелек в рабочих целях.&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Скам-сайты — генерация скомпрометированных ключей&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;С 2019 года хакеры используют генераторы онлайн-кошельков в качестве инструмента взлома. Такие сервисы могут выдавать одни и те же ключи разным пользователям или содержать уязвимости для их перехвата.&lt;/p&gt;
&lt;p&gt;Так, в июле 2023 года пользователь r/jdmcnair заявил о краже $3000 в биткоине из бумажного кошелька, который он сгенерировал в онлайн-сервисе.&lt;/p&gt;
&lt;p&gt;Как защититься: не пользоваться веб-сайтами — создавать адреса только в аппаратных устройствах или приложениях кошельков.&lt;/p&gt;
&lt;p&gt;Как создать безопасный кошелек&lt;/p&gt;
&lt;p&gt;Приватные ключи безопаснее большинства паролей, но и они могут стать уязвимыми из-за ошибок в приложениях и человеческого фактора.&lt;/p&gt;
&lt;p&gt;Чтобы избежать взлома, следуйте инструкции по созданию безопасного биткоин-кошелька:&lt;/p&gt;
&lt;p&gt;Не используйте сайты для генерации адресов — только аппаратные кошельки и приложения.&lt;br /&gt;
Не создавайте ключи из фраз и паролей, которые можете запомнить: они уязвимее комбинаций, созданных ГСЧ.&lt;br /&gt;
После генерации кошелька проверьте, действительно ли символы в нем случайны. Если более половины символов ключа — нули, он уязвим для брутфорса.&lt;br /&gt;
Кроме того, важно не использовать личные криптовалютные адреса для разработки Web3-приложений регулярно обновлять кошелек.&lt;/p&gt;
&lt;p&gt;Помните: приватные ключи нельзя отправлять третьим лицам, что бы они ни говорили.&lt;/p&gt;
</description>
</item>


</channel>
</rss>