{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Yuriy Gavrilov: posts tagged Security",
    "_rss_description": "Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov",
    "_rss_language": "en",
    "_itunes_email": "yvgavrilov@gmail.com",
    "_itunes_categories_xml": "",
    "_itunes_image": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic-square@2x.jpg?1643451008",
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/gavrilov.info\/tags\/security\/",
    "feed_url": "https:\/\/gavrilov.info\/tags\/security\/json\/",
    "icon": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic@2x.jpg?1643451008",
    "authors": [
        {
            "name": "Yuriy Gavrilov - B[u]g - for charity.gavrilov.eth",
            "url": "https:\/\/gavrilov.info\/",
            "avatar": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic@2x.jpg?1643451008"
        }
    ],
    "items": [
        {
            "id": "347",
            "url": "https:\/\/gavrilov.info\/all\/generaciya-sinteticheskih-dannyh-s-pomoschyu-sdv-ot-idei-do-goto\/",
            "title": "Генерация синтетических данных с помощью SDV: от идеи до готовой таблицы в ClickHouse",
            "content_html": "<p>Синтетические данные давно перестали быть просто «искусственной картинкой» — сегодня это полноценный инструмент для тестирования, разработки и даже обучения моделей машинного обучения. В этой статье я на примере реального кода покажу, как с помощью библиотеки <b>SDV ( <a href=\"https:\/\/github.com\/sdv-dev\/sdv\">Synthetic Data Vault <\/a> )<\/b> можно сгенерировать синтетическую копию существующей таблицы из ClickHouse, сохранив её статистические свойства и взаимосвязи.<\/p>\n<p>Весь код, который мы разберём, написан на Python и использует актуальную версию SDV. Спойлер: итоговый скрипт занимает меньше 80 строк, а результат — полностью готовая синтетическая таблица в вашей базе данных.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-240.png\" width=\"1280\" height=\"640\" alt=\"\" \/>\n<\/div>\n<hr \/>\n<h3>Что такое SDV и зачем он нужен<\/h3>\n<p><b>Synthetic Data Vault (SDV)<\/b> — это Python-библиотека с открытым исходным кодом, которая стала фактическим стандартом для генерации синтетических табличных данных. Она была создана в MIT, а сегодня развивается компанией DataCebo.<\/p>\n<p>Главная идея SDV проста: вы даёте ей реальные данные, она обучает генеративную модель, а затем эта модель создаёт новые данные, которые <b>статистически неотличимы<\/b> от оригинала, но при этом не содержат реальных записей.<\/p>\n<p>Ключевые возможности SDV:<\/p>\n<ul>\n<li><b>Обучение на одном наборе данных<\/b> — библиотека анализирует распределения, корреляции и зависимости между колонками.<\/li>\n<li><b>Генерация новых записей<\/b> — синтетические данные повторяют структуру и свойства оригинала.<\/li>\n<li><b>Оценка качества<\/b> — встроенные метрики показывают, насколько хорошо синтетика отражает реальные данные.<\/li>\n<li><b>Поддержка разных типов данных<\/b> — числовые, категориальные, даты, текстовые поля.<\/li>\n<\/ul>\n<p>SDV умеет работать с одиночными таблицами, связанными таблицами и даже последовательными данными.<\/p>\n<hr \/>\n<h3>Какие синтезаторы предлагает SDV<\/h3>\n<p>SDV предлагает несколько алгоритмов (синтезаторов) на выбор. В нашем примере мы используем <b>`GaussianCopulaSynthesizer`<\/b> — и вот почему.<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td style=\"text-align: center\">Синтезатор<\/td>\n<td style=\"text-align: center\">Принцип работы<\/td>\n<td style=\"text-align: center\">Скорость<\/td>\n<td style=\"text-align: center\">Когда использовать<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>GaussianCopulaSynthesizer<\/b><\/td>\n<td style=\"text-align: center\">Классический статистический метод, моделирует данные через многомерное распределение<\/td>\n<td style=\"text-align: center\">Очень быстрый<\/td>\n<td style=\"text-align: center\">Рекомендуется для старта: быстрая работа, хорошее качество, прозрачность<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>CTGANSynthesizer<\/b><\/td>\n<td style=\"text-align: center\">Генеративно-состязательная сеть (GAN)<\/td>\n<td style=\"text-align: center\">Медленнее<\/td>\n<td style=\"text-align: center\">Для данных со сложными зависимостями или большим количеством категориальных признаков<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>TVAESynthesizer<\/b><\/td>\n<td style=\"text-align: center\">Вариационный автокодировщик<\/td>\n<td style=\"text-align: center\">Средняя<\/td>\n<td style=\"text-align: center\">Альтернатива GAN, требующая больше данных для обучения<\/td>\n<\/tr>\n<\/table>\n<p>`GaussianCopulaSynthesizer` отлично справляется со смешанными типами данных, которые встречаются в реальных таблицах: числа, строки, даты. При этом он обучается за секунды даже на десятках тысяч строк. Именно поэтому мы выбрали его для нашего примера.<\/p>\n<hr \/>\n<h3>Настройка окружения<\/h3>\n<p>Перед запуском кода нам потребуется установить несколько пакетов. В нашем проекте мы использовали `uv` — быстрый менеджер пакетов для Python.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">uv pip install torch==2.2.2\nuv pip install &quot;numpy&lt;2&quot;\nuv pip install &quot;scipy&lt;1.13&quot;\nuv pip install sdv\nuv pip install clickhouse-connect<\/code><\/pre><blockquote>\n<p><b>Важно<\/b>: версии пакетов подобраны так, чтобы избежать конфликтов. На момент написания статьи `torch` версии 2.13.0 не имеет готовых сборок для macOS на Intel, поэтому мы используем `2.2.2`. Также важно зафиксировать `numpy<2` и `scipy<1.13` — более новые версии несовместимы с текущей версией `torch`.<\/p>\n<\/blockquote>\n<hr \/>\n<h3>Полный код генерации синтетических данных<\/h3>\n<p>Ниже представлен итоговый скрипт `sdv_py_v5.py`, который мы будем разбирать. Он подключается к ClickHouse, загружает реальные данные, обучает синтезатор, генерирует синтетическую копию и сохраняет результат обратно в базу.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">import clickhouse_connect\nimport pandas as pd\nimport os\nimport warnings\nfrom sdv.single_table import GaussianCopulaSynthesizer\nfrom sdv.metadata import SingleTableMetadata\n\n# Подавляем предупреждения (включая депрекацию)\nwarnings.filterwarnings(&quot;ignore&quot;)\n\n# Правильный импорт для однотабличных отчётов\nfrom sdmetrics.reports.single_table import QualityReport, DiagnosticReport\n\n# ========== НАСТРОЙКИ ==========\nCLICKHOUSE_HOST = 'localhost'\nCLICKHOUSE_PORT = 18123\nCLICKHOUSE_USER = 'default'\nCLICKHOUSE_PASSWORD = 'changeme'\nCLICKHOUSE_DATABASE = 'default'\n\nSOURCE_TABLE = 'superstore'\nSYNTHETIC_TABLE = f'{SOURCE_TABLE}_synt'\nLIMIT_ROWS = 10000\nNUM_SYNTHETIC_ROWS = None\n\n# ========== ПОДКЛЮЧЕНИЕ ==========\nclient = clickhouse_connect.get_client(\n    host=CLICKHOUSE_HOST,\n    port=CLICKHOUSE_PORT,\n    username=CLICKHOUSE_USER,\n    password=CLICKHOUSE_PASSWORD,\n    database=CLICKHOUSE_DATABASE\n)\n\n# ========== ЗАГРУЗКА ==========\nquery = f&quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&quot;\nreal_df = client.query_df(query)\nprint(f&quot;Загружено {len(real_df)} строк&quot;)\n\n# Преобразуем числовые колонки (запятая → точка)\nnumeric_cols = ['sales', 'discount', 'profit']\nfor col in numeric_cols:\n    if col in real_df.columns and real_df[col].dtype == 'object':\n        real_df[col] = real_df[col].str.replace(',', '.').astype(float)\n\n# ========== МЕТАДАННЫЕ ==========\nmetadata = SingleTableMetadata()\nmetadata.detect_from_dataframe(real_df)\n\nif os.path.exists('metadata.json'):\n    os.remove('metadata.json')\nmetadata.save_to_json('metadata.json')\nprint(&quot;Метаданные сохранены в metadata.json&quot;)\n\n# ========== ОБУЧЕНИЕ ==========\nprint(&quot;Начинаем обучение синтезатора...&quot;)\nsynthesizer = GaussianCopulaSynthesizer(metadata)\nsynthesizer.fit(real_df)\nprint(&quot;Обучение завершено&quot;)\n\n# ========== ГЕНЕРАЦИЯ ==========\nif NUM_SYNTHETIC_ROWS is None:\n    NUM_SYNTHETIC_ROWS = len(real_df)\nsynthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)\nprint(f&quot;Сгенерировано {len(synthetic_df)} строк&quot;)\n\n# ========== ПРЕДПРОСМОТР ==========\nprint(&quot;\\nОригинальные данные (первые 5 строк):&quot;)\nprint(real_df.head())\nprint(&quot;\\nСинтетические данные (первые 5 строк):&quot;)\nprint(synthetic_df.head())\n\n# ========== ОЦЕНКА КАЧЕСТВА ==========\nprint(&quot;\\n--- Диагностика (проверка ошибок) ---&quot;)\ndiagnostic = DiagnosticReport()\ndiagnostic.generate(real_df, synthetic_df, metadata.to_dict())\nprint(diagnostic)\n\nprint(&quot;\\n--- Оценка качества (статистическое сходство) ---&quot;)\nquality = QualityReport()\nquality.generate(real_df, synthetic_df, metadata.to_dict())\nprint(quality)\n\n# ========== СОХРАНЕНИЕ В CLICKHOUSE ==========\nclient.command(f&quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&quot;)\nclient.insert_df(SYNTHETIC_TABLE, synthetic_df)\nprint(f&quot;\\nСинтетические данные загружены в таблицу {SYNTHETIC_TABLE}&quot;)\n\n# ========== СОХРАНЕНИЕ В CSV ==========\nsynthetic_df.to_csv('synthetic_table.csv', index=False)\nprint(&quot;Синтетические данные также сохранены в synthetic_table.csv&quot;)<\/code><\/pre><hr \/>\n<h3>Разбор кода по шагам<\/h3>\n<h4>1. Подключение к ClickHouse и загрузка данных<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">client = clickhouse_connect.get_client(\n    host=CLICKHOUSE_HOST,\n    port=CLICKHOUSE_PORT,\n    username=CLICKHOUSE_USER,\n    password=CLICKHOUSE_PASSWORD,\n    database=CLICKHOUSE_DATABASE\n)\n\nquery = f&quot;SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}&quot;\nreal_df = client.query_df(query)<\/code><\/pre><p>Мы подключаемся к ClickHouse через библиотеку `clickhouse-connect` и загружаем данные из таблицы-источника в Pandas DataFrame. Лимит в 10 000 строк — разумный компромисс между качеством обучения и скоростью. Для большинства задач этого объёма достаточно, чтобы синтезатор уловил основные закономерности.<\/p>\n<h4>2. Предобработка числовых данных<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">numeric_cols = ['sales', 'discount', 'profit']\nfor col in numeric_cols:\n    if col in real_df.columns and real_df[col].dtype == 'object':\n        real_df[col] = real_df[col].str.replace(',', '.').astype(float)<\/code><\/pre><p>В нашем примере числовые колонки хранятся в ClickHouse как строки с запятой в качестве десятичного разделителя (европейский формат). Перед обучением мы преобразуем их в числа с плавающей точкой — иначе SDV не сможет корректно обработать эти данные.<\/p>\n<h4>3. Создание метаданных<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">metadata = SingleTableMetadata()\nmetadata.detect_from_dataframe(real_df)\nmetadata.save_to_json('metadata.json')<\/code><\/pre><p>SDV автоматически определяет типы каждой колонки: числовые, категориальные, даты и т.д.. Метаданные сохраняются в JSON-файл — это полезно для воспроизводимости: в следующий раз вы сможете загрузить их, а не пересоздавать заново.<\/p>\n<h4>4. Обучение синтезатора<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">synthesizer = GaussianCopulaSynthesizer(metadata)\nsynthesizer.fit(real_df)<\/code><\/pre><p>Синтезатор «изучает» ваши данные: анализирует распределения каждой колонки, корреляции между ними, паттерны пропусков. Этот процесс занимает секунды даже на 10 000 строк.<\/p>\n<h4>5. Генерация синтетических данных<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)<\/code><\/pre><p>Метод `sample()` создаёт нужное количество новых записей. В нашем случае мы генерируем столько же строк, сколько было в оригинале. При желании можно увеличить или уменьшить это число — синтезатор умеет масштабировать данные.<\/p>\n<h4>6. Оценка качества<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">diagnostic = DiagnosticReport()\ndiagnostic.generate(real_df, synthetic_df, metadata.to_dict())\n\nquality = QualityReport()\nquality.generate(real_df, synthetic_df, metadata.to_dict())<\/code><\/pre><p>Этот этап — одна из сильных сторон SDV. Мы проверяем два аспекта:<\/p>\n<ul>\n<li><b>Диагностика<\/b> (Data Validity + Data Structure) — проверяет, что синтетические данные корректны по типам и структуре. В нашем случае — 100%.<\/li>\n<li><b>Quality Report<\/b> — оценивает статистическое сходство с реальными данными по двум метрикам:\n<ul>\n  <li><b>Column Shapes Score<\/b> (90.77%) — насколько хорошо совпадают распределения отдельных колонок.<\/li>\n  <li><b>Column Pair Trends Score<\/b> (37.71%) — насколько хорошо сохранились попарные зависимости между колонками.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Общий Score 64.24% — это нормальный результат для демонстрационного примера. Для улучшения качества можно переключиться на `CTGANSynthesizer` или увеличить объём обучающих данных.<\/p>\n<h4>7. Сохранение в ClickHouse<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">client.command(f&quot;CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}&quot;)\nclient.insert_df(SYNTHETIC_TABLE, synthetic_df)<\/code><\/pre><p>Финальный шаг: создаём новую таблицу с той же структурой, что и исходная, и заполняем её синтетическими данными. Всё готово — вы можете работать с синтетической копией так же, как с реальной таблицей.<\/p>\n<hr \/>\n<h3>Интеграция с ClickHouse: почему это важно<\/h3>\n<p>ClickHouse — популярная колоночная СУБД для аналитики. Генерация синтетических данных прямо в экосистему ClickHouse открывает широкие возможности:<\/p>\n<ul>\n<li><b>Тестирование производительности<\/b> — можно генерировать датасеты любого размера и проверять, как ClickHouse справляется с нагрузкой.<\/li>\n<li><b>Разработка без доступа к продакшену<\/b> — разработчики получают рабочую копию данных без риска утечки конфиденциальной информации.<\/li>\n<li><b>Обучение моделей<\/b> — синтетические данные можно использовать для предварительного обучения ML-моделей, не затрагивая реальные данные.<\/li>\n<\/ul>\n<p>Альтернативный подход — использование встроенных средств ClickHouse, таких как движок `GenerateRandom`. Однако SDV даёт гораздо более качественные данные, потому что он не просто генерирует случайные значения, а воспроизводит реальные статистические паттерны.<\/p>\n<hr \/>\n<h3>Что дальше: улучшение качества синтеза<\/h3>\n<p>Если качество синтеза (особенно Column Pair Trends) вас не устраивает, вот несколько способов его улучшить:<\/p>\n<ol start=\"1\">\n<li><b>Увеличьте объём обучающих данных<\/b> — вместо 10 000 строк загрузите 50 000 или 100 000.<\/li>\n<li><b>Попробуйте CTGANSynthesizer<\/b> — нейросетевой синтезатор лучше справляется со сложными зависимостями.<\/li>\n<li><b>Настройте метаданные вручную<\/b> — если автоматическое определение типов сработало неидеально, вы можете отредактировать `metadata.json` и указать типы явно.<\/li>\n<li><b>Используйте условную генерацию<\/b> — SDV позволяет фиксировать значения отдельных колонок и генерировать остальные с учётом этих условий.<\/li>\n<\/ol>\n<hr \/>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-09-03-v-00.52.49.png\" width=\"1360\" height=\"708\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-09-03-v-00.53.29.png\" width=\"2016\" height=\"666\" alt=\"\" \/>\n<\/div>\n<hr \/>\n<h3>Заключение<\/h3>\n<p>Мы прошли полный путь: от установки библиотек до готовой синтетической таблицы в ClickHouse. SDV оказался мощным и при этом простым в использовании инструментом — весь процесс уместился в один скрипт на 80 строк.<\/p>\n<p>Главные выводы:<\/p>\n<ul>\n<li><b>SDV<\/b> — это не просто генератор случайных данных, а интеллектуальный инструмент, который сохраняет статистическую структуру оригинала.<\/li>\n<li><b>`GaussianCopulaSynthesizer`<\/b> — отличная точка входа: быстрый, прозрачный, даёт хорошее качество.<\/li>\n<li><b>Встроенная оценка качества<\/b> позволяет объективно понять, насколько синтетика похожа на реальные данные.<\/li>\n<li><b>Интеграция с ClickHouse<\/b> через `clickhouse-connect` делает процесс полностью автоматизированным.<\/li>\n<\/ul>\n<p>Синтетические данные открывают новые возможности для разработки, тестирования и анализа данных — без рисков, связанных с работой с реальными данными. А SDV даёт в руки инструмент, который превращает эту идею в реальность за считанные минуты.<\/p>\n<p>ПЫСЫ:<\/p>\n<p>Можно еще попробовать так: CTGANSynthesizer<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">from sdv.single_table import GaussianCopulaSynthesizer, CTGANSynthesizer<\/code><\/pre><p>Но надо будет дольше ждать...  и заменить тип в строке на<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">CTGANSynthesizer<\/code><\/pre><pre class=\"e2-text-code\"><code class=\"\">uv run sdv_py_v55.py\nЗагружено 9994 строк\nМетаданные сохранены в metadata.json\nНачинаем обучение синтезатора...\nPerformanceAlert: Using the CTGANSynthesizer on this data is not recommended. To model this data, CTGAN will generate a large number of columns.\n\nOriginal Column Name   Est # of Columns (CTGAN)\nOrder Date             1236\nShip Date              1334\nShip Mode              4\nCustomer Name          793\nsegment                3\nCountry\/Region         1\nregion                 4\ncategory               3\nSub-Category           17\nProduct Name           1849\nsales                  5825\nquantity               11\ndiscount               12\nprofit                 7287\n\nWe 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)<\/code><\/pre><p>Все .. комп полетел)) 5 мин... 7 мин... 15... чем то напоминает майнинг))) .... 20... 30... пойду пожалуй спать ... утром все еще майнит, видимо надо другие параметры указывать и разобраться лучше для чего эта опция. Первая же отработала очень быстро.<\/p>\n",
            "date_published": "2026-09-03T00:49:26+03:00",
            "date_modified": "2026-09-03T08:52:59+03:00",
            "tags": [
                "big data",
                "Data",
                "Database",
                "Security"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/image-240.png",
            "_date_published_rfc2822": "Thu, 03 Sep 2026 00:49:26 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "347",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/image-240.png",
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-09-03-v-00.52.49.png",
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-09-03-v-00.53.29.png"
                ]
            }
        },
        {
            "id": "345",
            "url": "https:\/\/gavrilov.info\/all\/upravlenie-dostupom-v-dashbordah-s-marimo-i-opa-prostoe-reshenie\/",
            "title": "Управление доступом в дашбордах с Marimo и OPA: простое решение для сложных политик",
            "content_html": "<p>В современном мире данных всё чаще требуется не только предоставлять пользователям интерактивные инструменты для анализа, но и жёстко контролировать, кто и к каким данным может обращаться. Классический подход — встраивать логику доступа прямо в код приложения — быстро становится негибким и трудно поддерживаемым. На помощь приходят специализированные решения: <b>Marimo<\/b> для построения дашбордов и <b>OPA<\/b> (Open Policy Agent) для централизованного управления политиками доступа.<\/p>\n<p>В этой статье мы разберём, как написать простое приложение на Marimo, которое проверяет права пользователя через OPA, а затем обсудим, как эта связка может быть расширена на полноценный дашборд, работающий с Trino и управляющий доступом к данным на разных уровнях.<\/p>\n<hr \/>\n<h3>Что такое Marimo и OPA?<\/h3>\n<p><b>Marimo<\/b> (<a href=\"https:\/\/github.com\/marimo-team\/marimo)\">https:\/\/github.com\/marimo-team\/marimo)<\/a> — это современный интерактивный блокнот для Python, который сочетает в себе удобство Jupyter с реактивностью и возможностью превращать блокнот в веб-приложение. В отличие от классических блокнотов, Marimo автоматически пересчитывает ячейки при изменении входных данных, что делает его идеальным для создания дашбордов и инструментов анализа.<\/p>\n<p><b>OPA<\/b> (Open Policy Agent: <a href=\"https:\/\/www.openpolicyagent.org)\">https:\/\/www.openpolicyagent.org)<\/a> — это универсальный движок политик с открытым исходным кодом. Он позволяет описывать правила доступа на языке Rego (декларативном, похожем на JSON) и принимать решения на основе входных данных (input). OPA работает как отдельный сервис, принимающий запросы и возвращающий разрешено или запрещено действие. Такой подход отделяет политики от кода приложения, упрощая их изменение, аудит и повторное использование.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-08-28-v-00.13.05.png\" width=\"1184\" height=\"1682\" alt=\"\" \/>\n<\/div>\n<hr \/>\n<h3>Простой пример: проверка доступа в Marimo<\/h3>\n<p>Представьте, что у нас есть дашборд, в котором разные пользователи могут видеть разные разделы. Вместо того чтобы хардкодить условия в Python, мы выносим логику в OPA.<\/p>\n<p>Ниже приведён фрагмент кода на Marimo, который реализует минимальный интерфейс для проверки доступа:<\/p>\n<p>Запускаем OPA<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">podman run -d --name opa-server -p 8181:8181 openpolicyagent\/opa \\                \n  run --server --addr=0.0.0.0:8181 --log-level debug<\/code><\/pre><p>Создаем политику Rego<\/p>\n<p>nano policy.rego<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">package app.authz\ndefault allow = false\nallow if {\n    input.user.role == &quot;admin&quot;\n}<\/code><\/pre><p>Отправляем политику в OPA:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">curl -X PUT --data-binary @policy.rego http:\/\/localhost:8181\/v1\/policies\/my_policy<\/code><\/pre><p>Далее запускаем новый блокнот Marimo<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">mkdir marimo-opa\ncd marimo-opa\nuv init \nuv add marimo requests\nuv run marimo edit app.py<\/code><\/pre><p>а теперь само приложение Marimo<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">import marimo as mo\nimport requests\n\n# Элементы управления\nuser_role = mo.ui.dropdown([&quot;user&quot;, &quot;admin&quot;], value=&quot;user&quot;, label=&quot;Роль пользователя:&quot;)\nresource = mo.ui.text(value=&quot;dashboard&quot;, label=&quot;Ресурс:&quot;)\nsubmit = mo.ui.button(label=&quot;Проверить доступ&quot;)\n\nmo.hstack([user_role, resource, submit])<\/code><\/pre><p>После нажатия кнопки код отправляет запрос к OPA:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">mo.stop(not submit.value, mo.md(&quot;*Нажмите кнопку для проверки прав*&quot;))\n\nopa_url = &quot;http:\/\/localhost:8181\/v1\/data\/app\/authz\/allow&quot;\npayload = {\n    &quot;input&quot;: {\n        &quot;user&quot;: {&quot;role&quot;: user_role.value},\n        &quot;resource&quot;: resource.value\n    }\n}\n\ntry:\n    response = requests.post(opa_url, json=payload).json()\n    is_allowed = response.get(&quot;result&quot;, False)\n    status = mo.md(&quot;**Доступ разрешен**&quot;) if is_allowed else mo.md(&quot;**Доступ запрещен**&quot;)\nexcept Exception as e:\n    status = mo.md(f&quot;**Ошибка подключения к ОРА:** {e}&quot;)\n\nstatus<\/code><\/pre><p>Что здесь происходит?<\/p>\n<ul>\n<li>Пользователь выбирает роль (user\/admin) и вводит название ресурса.<\/li>\n<li>При клике на кнопку формируется JSON с полем `input`, содержащим роль и ресурс.<\/li>\n<li>Этот JSON отправляется в OPA по эндпоинту, который возвращает решение (`result` — true\/false).<\/li>\n<li>На основе результата выводится сообщение о разрешении или запрете.<\/li>\n<\/ul>\n<p>Этот пример демонстрирует, как легко интегрировать OPA в интерфейс на Marimo. Все политики (например, `admin` может всё, а `user` — только определённые ресурсы) хранятся отдельно в OPA и могут быть изменены без переписывания кода приложения.<\/p>\n<hr \/>\n<h3>Расширяем сценарий: дашборд на Trino с двойным контролем доступа<\/h3>\n<p>Теперь представим более реальную задачу: мы строим дашборд для аналитики, который выполняет SQL-запросы к <b>Trino<\/b> — распределённому движку для работы с большими данными. В Trino доступ к таблицам, схемам и столбцам также можно регулировать через OPA. Таким образом, у нас возникает два уровня авторизации:<\/p>\n<ol start=\"1\">\n<li><b>Уровень приложения (Marimo)<\/b> — определяет, может ли пользователь вообще открыть определённый раздел дашборда или выполнить какое-то действие в интерфейсе.<\/li>\n<li><b>Уровень данных (Trino)<\/b> — контролирует, какие именно данные (таблицы, колонки, строки) пользователь может запрашивать через SQL.<\/li>\n<\/ol>\n<p>Эти два уровня могут обслуживаться <b>разными экземплярами OPA<\/b> или одним, но с разными пакетами политик. Например, в Marimo мы проверяем политику `app\/authz\/allow`, а в Trino — `trino\/authz\/allow`. Это даёт гибкость: политики для интерфейса и для данных могут управляться разными командами или обновляться независимо.<\/p>\n<p>В нашем приложении Marimo после успешной проверки прав на доступ к разделу мы можем формировать SQL-запрос и отправлять его в Trino. При этом Trino, в свою очередь, проверит, имеет ли пользователь право читать запрашиваемые таблицы, используя свой OPA-агент. Если хотя бы один из агентов вернёт отказ, пользователь не получит данные.<\/p>\n<p>Такая двухуровневая архитектура обеспечивает безопасность «в глубину» и позволяет тонко настраивать политики как на уровне интерфейса, так и на уровне сырых данных.<\/p>\n<hr \/>\n<h3>Управление политиками OPA: взгляд в будущее<\/h3>\n<p>Настройка и поддержка политик OPA, особенно когда речь идёт о десятках таблиц, ролей и атрибутов, может стать сложной задачей. Требуется не только писать правила на Rego, но и поддерживать актуальность данных о пользователях и ресурсах. Для упрощения этой работы существует проект <b>Moat<\/b> (Data Control Plane для Trino и OPA).<\/p>\n<p>Moat предоставляет: <a href=\"https:\/\/github.com\/moat-io\/moat\">https:\/\/github.com\/moat-io\/moat<\/a><\/p>\n<ul>\n<li>SCIM2.0-сервер для интеграции с провайдерами идентичности (Okta, EntraId и др.);<\/li>\n<li>ингестию атрибутов пользователей и групп из различных источников (SQL, LDAP);<\/li>\n<li>ингестию метаданных о таблицах и представлениях из каталогов данных;<\/li>\n<li>готовые политики Rego для типовых сценариев (RBAC, ABAC);<\/li>\n<li>OPA-совместимый Bundle API с кешированием для быстрого обновления политик.<\/li>\n<\/ul>\n<p>Moat сам не принимает решений в рантайме — он лишь поставляет OPA необходимую информацию (политики и данные). Это позволяет удобно управлять множеством кластеров Trino и эфемерных окружений, добавляя OPA-контейнер в каждый координатор и указывая ему на Moat как источник бандлов.<\/p>\n<p>Однако подробное рассмотрение Moat выходит за рамки этой статьи. Мы обязательно вернёмся к нему в отдельном материале, где разберём его архитектуру, настройку и примеры использования.<\/p>\n<hr \/>\n<h3>Заключение<\/h3>\n<p>Связка Marimo и OPA даёт разработчикам дашбордов мощный и гибкий инструмент для управления доступом. Вы можете отделить политики от кода, упростить их изменение и аудит, а также комбинировать несколько OPA-агентов для разных уровней — приложения и данных. В сочетании с Trino и такими инструментами, как Moat, эта экосистема становится полноценным решением для корпоративных аналитических платформ.<\/p>\n<p>Попробуйте предложенный пример в своём проекте — и вы убедитесь, как легко внедрить централизованное управление доступом, не усложняя код приложения. А о Moat мы расскажем в следующий раз!<\/p>\n",
            "date_published": "2026-08-28T00:14:17+03:00",
            "date_modified": "2026-08-28T00:16:01+03:00",
            "tags": [
                "Data",
                "Open Source",
                "Python",
                "Security"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-08-28-v-00.13.05.png",
            "_date_published_rfc2822": "Fri, 28 Aug 2026 00:14:17 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "345",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-08-28-v-00.13.05.png"
                ]
            }
        },
        {
            "id": "312",
            "url": "https:\/\/gavrilov.info\/all\/anatomiya-nevidimosti-gid-po-reklamnym-identifikatoram-2025\/",
            "title": "Анатомия невидимости: гид по рекламным идентификаторам (2025+)",
            "content_html": "<p>В современном маркетинге данные — это новая нефть, а <b>рекламный идентификатор (Advertising ID)<\/b> — это трубопровод, по которому эта нефть течет. От смартфона в кармане до умного телевизора в гостиной: каждое устройство имеет свой цифровой паспорт.<\/p>\n<p>В этой статье мы разберем не только скрытую механику «рекламной слежки», но и юридические риски для бизнеса в РФ, новые технологии обхода блокировок и то, как клиентский опыт (CX) меняется в эпоху тотальной приватности.<\/p>\n<hr \/>\n<h3>1. Зоопарк идентификаторов: Кто есть кто<\/h3>\n<p>Рынок рекламных ID фрагментирован. Каждый сегмент решает одну задачу — узнать пользователя, — но делает это разными способами.<\/p>\n<h4>📱 Мобильные устройства (MAID — Mobile Advertising IDs)<\/h4>\n<p>Это самые ценные идентификаторы, так как смартфон является наиболее персональным (“интимным”) устройством.<\/p>\n<ul>\n<li><b>IDFA (Identifier for Advertisers):<\/b> Стандарт Apple (iOS). После внедрения *App Tracking Transparency (ATT)* в iOS 14.5 доступ к нему закрыт по умолчанию.  <br \/>\n> <b>Важно:<\/b> Лишь 20-30% пользователей в мире нажимают «Разрешить» (Allow Tracking). Это создало огромную «слепую зону» в аналитике.<\/li>\n<li><b>GAID (Google Advertising ID) \/ AAID:<\/b> Аналог для Android. Позволяет связывать активность пользователя между разными приложениями. Google также движется в сторону ограничения доступа через инициативу Privacy Sandbox on Android.<\/li>\n<\/ul>\n<h4>📺 Телевизоры и Set-Top Box (CTV IDs)<\/h4>\n<p>С ростом Smart TV и стримингов маркетологи теперь трекают пользователей «на диване».<\/p>\n<ul>\n<li><b>Примеры:<\/b> TIFA (Samsung), Roku ID, Amazon Fire TV ID.<\/li>\n<li><b>Логика Household (Домохозяйство):<\/b> В отличие от личных смартфонов, эти ID часто привязаны к семье.\n<ul>\n  <li>*Инсайт эксперта по данным:* Это создает проблему «шумных данных». Если вы рекламируете женские духи, а телевизор смотрит муж или ребенок, атрибуция будет ошибочной. Для очистки данных используются Cross-Device графы, связывающие TV ID с мобильными телефонами, находящимися в той же Wi-Fi сети.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>🌐 Веб-идентификаторы<\/h4>\n<ul>\n<li><b>Third-Party Cookies:<\/b> Старейший и умирающий стандарт. Текстовые файлы, оставляемые рекламными сетями (не владельцем сайта) в браузере.<\/li>\n<li><b>Stable IDs \/ Hashed Emails:<\/b> Новая валюта рынка. Это зашифрованные (хэшированные) адреса электронной почты или номера телефонов. Используются в таких решениях, как *Unified ID 2.0*.<\/li>\n<\/ul>\n<p><details><br \/>\n<summary><b>🔍 Юридический комментарий: Персональные данные в РФ<\/b><\/summary><\/p>\n<p>Согласно <b>152-ФЗ «О персональных данных»<\/b> <a href=\"https:\/\/normativ.kontur.ru\/document?moduleId=1&documentId=501173\">normativ.kontur.ru<\/a> и позиции Роскомнадзора, любые данные, которые позволяют (даже косвенно) идентифицировать личность, могут считаться персональными данными (ПДн).<\/p>\n<ul>\n<li><b>Является ли IDFA\/GAID персональными данными?<\/b> Формально — нет, это псевдонимизированные данные. <b>НО:<\/b> Как только вы обогащаете этот ID номером телефона из вашей CRM или связываете его с профилем конкретного клиента, он становится ПДн.<\/li>\n<li><b>Риски:<\/b> Хранение баз с “просто ID” безопаснее, но как только происходит «склейка» (matching) с реальным человеком, вы обязаны иметь согласие на обработку (и часто — на передачу третьим лицам, т.е. рекламным сетям).<\/li>\n<li><b>Штрафы:<\/b> За нарушение правил обработки ПДн штрафы для юрлиц могут достигать 18 млн рублей (при повторном нарушении при локализации), а за утечки — вплоть до оборотных штрафов (обсуждаемые поправки). Подробнее о сборе данных <a href=\"https:\/\/adesk.ru\/blog\/kak-biznesu-sobirat-i-khranit-personalnye-dannye-chtoby-ne-poluchit-shtraf\/\">adesk.ru<\/a>.<br \/>\n<\/details><\/li>\n<\/ul>\n<hr \/>\n<h3>2. Механика: Как они строятся и живут<\/h3>\n<h4>Формула генерации<\/h4>\n<p>Большинство мобильных ID (GAID, IDFA) представляют собой <b>UUID (Universally Unique Identifier) версии 4<\/b>. Это 128-битное число.<\/p>\n<p>$$ P(collision) \\approx \\frac{n^2}{2 \\times 2^{128}} $$<\/p>\n<p>Вероятность совпадения двух таких ID астрономически мала.<\/p>\n<ul>\n<li><b>Пример:<\/b> `123e4567-e89b-12d3-a456-426614174000`<\/li>\n<li><b>Генерация:<\/b> Алгоритм использует криптографически стойкий генератор случайных чисел (CSPRNG) + энтропию системы (время запуска, «шум» железа).<\/li>\n<\/ul>\n<h4>Жизненный цикл и безопасность<\/h4>\n<p>Главное отличие рекламного ID от аппаратного (IMEI) — возможность сброса (<b>Resettability<\/b>).<\/p>\n<ol start=\"1\">\n<li><b>Действие пользователя:<\/b> В настройках конфиденциальности нажимается «Сбросить рекламный ID».<\/li>\n<li><b>Реакция ОС:<\/b> Генерируется новый UUID.<\/li>\n<li><b>Результат:<\/b> Для рекламных сетей устройство становится «чистым листом». История интересов разрывается.<\/li>\n<\/ol>\n<hr \/>\n<h3>3. E-commerce: Сквозь экраны к покупке<\/h3>\n<p>В интернет-коммерции ID — это клей, собирающий разрозненные клики в путь покупателя (Customer Journey Map).<\/p>\n<h4>Сквозная аналитика (Cross-Device)<\/h4>\n<p>Как понять, что телефон `User_A` и ноутбук `Cookie_B` — это один человек?<\/p>\n<ol start=\"1\">\n<li><b>Deterministic (Точный метод):<\/b> «Золотой стандарт». Пользователь залогинился в магазине под своим Email на обоих устройствах. Связка 100% достоверна.<\/li>\n<li><b>Probabilistic (Вероятностный метод):<\/b> Система видит, что телефон и ноутбук ежедневно выходят в сеть с одного IP-адреса Wi-Fi в одно время, имеют похожие паттерны посещения сайтов. Алгоритмы с вероятностью 90%+ «склеивают» профили в один Household.<\/li>\n<\/ol>\n<h4>Механика таргетинга (RTB – Real Time Bidding)<\/h4>\n<p>Процесс показа рекламы занимает <b>менее 100 миллисекунд<\/b>:<\/p>\n<ol start=\"1\">\n<li>Вы смотрите кроссовки в приложении (система фиксирует ваш `GAID`).<\/li>\n<li>Вы открываете новостной сайт. Сайт отправляет ваш `GAID` на рекламную биржу.<\/li>\n<li>DSP (платформа закупки) узнает ваш ID в базе сегментов: *«Это тот же, кто смотрел Nike 5 минут назад!»*.<\/li>\n<li>Происходит мгновенный аукцион, ставка выигрывает, и вам показывается баннер.<\/li>\n<\/ol>\n<hr \/>\n<h3>4. Феномен Amazon Ads и Retail Media<\/h3>\n<p>Amazon (и его аналоги в РФ) стоит особняком. Это закрытая экосистема (<b>Walled Garden<\/b>), чья сила не в технологиях трекинга, а в транзакционных данных. Им не нужно *угадывать*, что вы хотите купить, они *знают*, что вы покупаете.<\/p>\n<h4>Идентификатор Amazon<\/h4>\n<p>В основе лежит не «летучий» UUID устройства, а <b>Internal Customer ID<\/b>, жестко привязанный к аккаунту.<\/p>\n<ul>\n<li><b>Формула матчинга:<\/b> Для обмена данными с внешним миром используется <b>Hashed Email (HEM)<\/b>. Ваш email превращается в необратимую строку (обычно SHA-256).<\/li>\n<li><b>Clean Rooms (AMC):<\/b> Amazon Marketing Cloud позволяет крупным брендам загружать свои CRM-данные в защищенную среду, где они пересекаются с данными Amazon. Рекламодатель получает инсайты (например, “Клиенты, купившие кофемашину у нас на сайте, покупают капсулы на Amazon”), но не видит персональных данных конкретных людей.<\/li>\n<\/ul>\n<hr \/>\n<h3>5. Война за приватность и обходные пути<\/h3>\n<p>Индустрия находится в состоянии холодной войны между запросом на приватность и эффективностью.<\/p>\n<h4>Главные сложности<\/h4>\n<ul>\n<li><b>Apple ATT:<\/b> Обрушение эффективности рекламы Facebook на iOS. Стоимость привлечения клиента (CAC) выросла на 40-60%.<\/li>\n<li><b>Смерть Cookies:<\/b> Google Chrome (хоть и откладывает полное отключение) внедряет Privacy Sandbox, заменяя индивидуальные куки на FLoC\/Topics API (группировку по интересам).<\/li>\n<li><b>Блокировщики:<\/b> AdBlock режет запросы к доменам трекеров. (на уровне DNS, например AdGuard)<\/li>\n<\/ul>\n<h4>Как рынок обходит блокировки? Технический Deep Dive<\/h4>\n<ol start=\"1\">\n<li><b>Server-Side Tracking (S2S \/ CAPI):<\/b>  <br \/>\nВместо отправки данных пикселем из браузера (JS), данные о покупке отправляются напрямую с бэкенда магазина на сервер рекламной системы (например, через Facebook Conversions API).<\/li>\n\n<ul>\n  <li>Плюс:* Не блокируется AdBlock и браузерами. Точность данных выше.<\/li>\n  <li>Минус:* Сложная техническая реализация. Требует согласия пользователя на передачу данных.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Fingerprinting (Серый метод):<\/b>  <br \/>\nСбор уникальных параметров устройства без использования cookie:<\/li>\n\n<ul>\n  <li>`Screen Resolution` + `User Agent` + `Battery Level` + `System Fonts` + `AudioContext`<\/li>\n  <li>Такой “цифровой отпечаток” уникален для 95% пользователей. Apple и Google активно борются с этим методом, считая его нарушением приватности.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<hr \/>\n<h3>Итог: Тренды 2025+ и рекомендации<\/h3>\n<p>Эра «дикого запада», когда можно было незаметно следить за каждым шагом, заканчивается. Мы переходим в эру агрегированных данных и доверительного маркетинга (Zero-Party Data).<\/p>\n<h4>Ключевые тренды:<\/h4>\n<ol start=\"1\">\n<li><b>First-Party Data — король:<\/b> Компании, владеющие собственными данными и прямым контактом с клиентом (Email, App), выигрывают. Зависимость от Facebook становится токсичной.<\/li>\n<li><b>Retail Media Networks:<\/b> Бум рекламных сетей маркетплейсов. Они обладают данными о деньгах, а не о кликах.<\/li>\n<li><b>AI вместо Cookies:<\/b> Алгоритмы машинного обучения будут «достраивать» потерянные данные. Например, Google GA4 уже использует моделирование конверсий для пользователей, отказавшихся от трекинга.<\/li>\n<\/ol>\n<h4>✅ Рекомендация<\/h4>\n<ul>\n<li><b>Инвестируйте в CDP (Customer Data Platform):<\/b> Собирайте все данные (CRM, сайт, приложение) в одном месте.<\/li>\n<li><b>Внедряйте Server-Side трекинг:<\/b> Это единственный способ сохранить точность аналитики в будущем.<\/li>\n<li><b>Тестируйте новые каналы:<\/b> Telegram Ads (работает без кук, на контексте каналов) или Retail Media.<\/li>\n<li><b>Аудит согласий:<\/b> Проверьте формы сбора данных на сайте. Галочка «Согласен на рекламную рассылку» должна быть отделена от «Согласен на обработку ПДн». Но мне, если честно, не нравится такой подход. Я бы сделал так – Типа Посмотри 10 рекламных роликов, и спи спокойно сегодня до 12, больше показывать сегодня не буду типа)))<\/li>\n<li><b>Обезличивание:<\/b> Используйте методы обезличивания (деперсонализации) при передаче данных партнерам, как того требуют новые правила <a href=\"https:\/\/www.consultant.ru\/document\/cons_doc_LAW_511607\/d3d38cd263a833779d35b1d4892762b85632b1b4\/\">consultant.ru<\/a>.<\/li>\n<li><b>Цели обработки:<\/b> Четко прописывайте цели в политике конфиденциальности (например, не просто “маркетинг”, а “таргетирование рекламы в сетях Яндекса”) <a href=\"https:\/\/rppa.pro\/analitika\/celi_obrabotki_pdn\">rppa.pro<\/a>. Кстати, хороший справочник.<\/li>\n<\/ul>\n",
            "date_published": "2026-01-20T22:16:15+03:00",
            "date_modified": "2026-01-20T23:50:20+03:00",
            "tags": [
                "Ad",
                "Data",
                "Security"
            ],
            "_date_published_rfc2822": "Tue, 20 Jan 2026 22:16:15 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "312",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "295",
            "url": "https:\/\/gavrilov.info\/all\/obrabotka-logov-trino-iz-kafka-s-pomoschyu-vector-dlya-udaleniya\/",
            "title": "Обработка логов Trino из Kafka с помощью Vector для удаления полей",
            "content_html": "<p>В современных архитектурах данных, построенных на Kafka, часто возникает задача обработки или фильтрации потока событий “на лету”. Один из распространенных кейсов — удаление чувствительной информации из логов перед их передачей в следующую систему (например, в SIEM или систему долгосрочного хранения).<\/p>\n<p>Kafka: <a href=\"https:\/\/hub.docker.com\/r\/apache\/kafka\">https:\/\/hub.docker.com\/r\/apache\/kafka<\/a><br \/>\nVector: <a href=\"https:\/\/vector.dev\/docs\">https:\/\/vector.dev\/docs<\/a><\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-11-21-v-00.28.37.png\" width=\"1662\" height=\"720\" alt=\"\" \/>\n<\/div>\n<p>Рассмотрим реальный пример:<\/p>\n<ul>\n<li>Кластер <b>Trino<\/b> (или Presto) пишет подробные логи о каждом выполненном запросе в топик Kafka.<\/li>\n<li>Эти логи содержат как полезные метаданные (пользователь, время, объем данных), так и полную <b>текстовую версию самого SQL-запроса<\/b> в поле, например, `query`.<\/li>\n<li>Задача<b>: Переложить эти логи в другой топик Kafka, но уже <\/b>без** поля `query`, чтобы система-подписчик не имела доступа к потенциально конфиденциальной информации в текстах запросов.<\/li>\n<\/ul>\n<p>Для решения этой задачи мы воспользуемся <b>Vector<\/b> — легковесным и сверхбыстрым инструментом для обработки данных.<\/p>\n<h4>План действий<\/h4>\n<ol start=\"1\">\n<li>Создадим два топика в Kafka: `trino-logs-raw` (для сырых логов) и `trino-logs-cleaned` (для очищенных).<\/li>\n<li>Настроим Vector для чтения из первого топика, удаления поля `query` и всех служебных метаданных.<\/li>\n<li>Настроим Vector на запись результата во второй топик.<\/li>\n<li>Запустим всю цепочку в Docker и протестируем.<\/li>\n<\/ol>\n<h4>Шаг 1: Подготовка Kafka<\/h4>\n<p>Предполагается, что у вас уже запущен Kafka-брокер в Docker. На основе нашего примера, у вас есть контейнер с именем `broker1`, который является частью Docker-сети `minimal_iceberg_net`.<\/p>\n<p>Откройте терминал и подключитесь к контейнеру Kafka, чтобы создать топики:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">Создадим сеть \n\ndocker network create my_net \n\nЗапускаем брокер broker:\n\ndocker run -d \\\n  --name broker3 \\\n  --network=my_net \\\n  -p 8893:9092 \\\n  -e KAFKA_NODE_ID=3 \\\n  -e KAFKA_PROCESS_ROLES='broker,controller' \\\n  -e KAFKA_CONTROLLER_QUORUM_VOTERS='3@broker3:9093' \\\n  -e KAFKA_LISTENERS='INTERNAL:\/\/0.0.0.0:29092,EXTERNAL:\/\/0.0.0.0:9092,CONTROLLER:\/\/broker3:9093' \\\n  -e KAFKA_ADVERTISED_LISTENERS='INTERNAL:\/\/broker3:29092,EXTERNAL:\/\/localhost:8893' \\\n  -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP='INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT' \\\n  -e KAFKA_INTER_BROKER_LISTENER_NAME='INTERNAL' \\\n  -e KAFKA_CONTROLLER_LISTENER_NAMES='CONTROLLER' \\\n  -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \\\n  -e KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1 \\\n  -e KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1 \\\n  apache\/kafka:latest\n\n\ndocker exec --workdir \/opt\/kafka\/bin\/ -it broker3 sh<\/code><\/pre><p>Теперь, находясь внутри контейнера, выполните команды:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># Создаем &quot;сырой&quot; топик для входящих логов Trino\n.\/kafka-topics.sh --create --topic trino-logs-raw --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1\n\n# Создаем &quot;чистый&quot; топик для обработанных логов\n.\/kafka-topics.sh --create --topic trino-logs-cleaned --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1<\/code><\/pre><p>*Обратите внимание: я использую внутренний порт брокера `29092`, который узнали ранее.*<\/p>\n<p>Выйдите из контейнера командой `exit`.<\/p>\n<h4>Шаг 2: Конфигурация Vector<\/h4>\n<p>На вашей локальной машине создайте структуру папок:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">vector-trino-processor\/\n└── config\/\n    └── vector.toml<\/code><\/pre><p>Поместите в файл `vector.toml` следующую конфигурацию. Это сердце нашего решения.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># vector-trino-processor\/config\/vector.toml\n\n# ==================================\n#          ИСТОЧНИК ДАННЫХ\n# ==================================\n# Читаем сырые логи из Kafka\n[sources.trino_raw_logs]\n  type = &quot;kafka&quot;\n  # Подключаемся к брокеру по имени контейнера и внутреннему порту\n  bootstrap_servers = &quot;broker3:29092&quot;\n  # Указываем, какой топик слушать\n  topics = [&quot;trino-logs-raw&quot;]\n  group_id = &quot;vector-trino-cleaner&quot;\n  # Vector автоматически распарсит входящие сообщения как JSON\n  decoding.codec = &quot;json&quot;\n\n# ==================================\n#             ТРАНСФОРМАЦИЯ\n# ==================================\n# Удаляем поле `query` и служебные метаданные Vector\n[transforms.clean_trino_log]\n  type = &quot;remap&quot;\n  # Получаем данные от нашего источника\n  inputs = [&quot;trino_raw_logs&quot;]\n  # Скрипт на языке Vector Remap Language (VRL)\n  source = '''\n  # 1. Удаляем чувствительное поле &quot;query&quot; из лога.\n  del(.query)\n\n  # 2. Удаляем все служебные поля, которые Vector добавляет\n  #    при чтении из Kafka, чтобы на выходе был чистый JSON.\n  del(.headers)\n  del(.message_key)\n  del(.offset)\n  del(.partition)\n  del(.source_type)\n  del(.timestamp)\n  del(.topic)\n  '''\n\n# ==================================\n#           ПРИЕМНИК ДАННЫХ\n# ==================================\n# Пишем очищенные логи в новый топик Kafka\n[sinks.trino_cleaned_logs]\n  type = &quot;kafka&quot;\n  # Принимаем на вход данные, прошедшие трансформацию\n  inputs = [&quot;clean_trino_log&quot;]\n  bootstrap_servers = &quot;broker3:29092&quot;\n  # Указываем топик для записи\n  topic = &quot;trino-logs-cleaned&quot;\n  # Кодируем итоговое событие обратно в JSON\n  encoding.codec = &quot;json&quot;<\/code><\/pre><h4>Шаг 3: Запуск и Тестирование<\/h4>\n<p>Нам понадобится три терминала.<\/p>\n<p><b>В Терминале №1 — Запустим Vector<\/b><\/p>\n<p>Перейдите в папку `vector-trino-processor` и выполните команду:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">docker run \\\n  -d \\\n  --name vector-processor \\\n  -v &quot;$(pwd)\/config:\/etc\/vector\/&quot; \\\n  --network=my_net \\\n  --rm \\\n  timberio\/vector:latest-alpine --config \/etc\/vector\/vector.toml<\/code><\/pre><p>Эта команда:<\/p>\n<ul>\n<li>Запускает контейнер Vector в фоновом режиме (`-d`).<\/li>\n<li>Дает ему имя `vector-processor`.<\/li>\n<li>Монтирует ваш локальный конфиг (`-v`).<\/li>\n<li>Подключает его к той же сети, что и Kafka (`--network`).<\/li>\n<li>Явно указывает, какой файл конфигурации использовать (`--config`).<\/li>\n<\/ul>\n<p><b>В Терминале №2 — Симулируем отправку лога Trino<\/b><\/p>\n<p>Запустим интерактивный Kafka-продюсер.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">docker exec --workdir \/opt\/kafka\/bin -it broker3 .\/kafka-console-producer.sh --topic trino-logs-raw --bootstrap-server localhost:29092<\/code><\/pre><p>Теперь вставьте в этот терминал JSON, имитирующий лог от Trino, и нажмите Enter:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">{&quot;user&quot;:&quot;yuriy&quot;,&quot;source&quot;:&quot;trino-cli&quot;,&quot;queryId&quot;:&quot;20231120_123456_00001_abcde&quot;,&quot;query&quot;:&quot;SELECT * FROM sensitive_table a JOIN other_table b ON a.id = b.id WHERE a.credit_card = '1234-5678-9012-3456'&quot;,&quot;state&quot;:&quot;FINISHED&quot;}<\/code><\/pre><p><b>В Терминале №3 — Проверяем результат<\/b><\/p>\n<p>Запустим Kafka-консьюмер, который будет слушать <b>очищенный<\/b> топик `trino-logs-cleaned`.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">docker exec --workdir \/opt\/kafka\/bin -it broker3 .\/kafka-console-consumer.sh --topic trino-logs-cleaned --bootstrap-server localhost:29092 --from-beginning<\/code><\/pre><p>Вы практически мгновенно увидите результат работы Vector — тот же самый лог, но уже <b>без поля `query`<\/b>:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">{&quot;user&quot;:&quot;yuriy&quot;,&quot;source&quot;:&quot;trino-cli&quot;,&quot;queryId&quot;:&quot;20231120_123456_00001_abcde&quot;,&quot;state&quot;:&quot;FINISHED&quot;}<\/code><\/pre><p>Мы построили простой, но мощный конвейер для обработки данных в режиме реального времени, решив поставленную задачу с минимальными усилиями.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-11-21-v-01.25.17.png\" width=\"1652\" height=\"470\" alt=\"\" \/>\n<\/div>\n",
            "date_published": "2025-11-21T01:27:16+03:00",
            "date_modified": "2025-11-21T01:27:11+03:00",
            "tags": [
                "big data",
                "Data",
                "Data Engineer",
                "Security"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-11-21-v-00.28.37.png",
            "_date_published_rfc2822": "Fri, 21 Nov 2025 01:27:16 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "295",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-11-21-v-00.28.37.png",
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-11-21-v-01.25.17.png"
                ]
            }
        },
        {
            "id": "274",
            "url": "https:\/\/gavrilov.info\/all\/i-esche-nemnogo-pro-bezopasnost-v-masshtabe\/",
            "title": "И еще немного про безопасность в масштабе",
            "content_html": "<h4>Ranger vs. OPA: Битва архитектур... и почему OPAL меняет правила игры<\/h4>\n<pre class=\"e2-text-code\"><code class=\"\">● Ranger has a fixed development model\n● To add new systems you need to write new modules,\ncompile and roll out Ranger\n● OPA is all REST\n● Basically everything is configuration\n● We can build the 80% abstraction layer easily\n● Anybody else -&gt; they can build whatever extra they need -&gt; in config!<\/code><\/pre><p>В мире современных распределённых систем управление доступом (авторизация) — одна из самых сложных и критически важных задач. Компании постоянно ищут баланс между безопасностью, гибкостью и скоростью разработки. Начальные тезисы были абсолютно точны:<\/p>\n<blockquote>\n<p>У Ranger фиксированная модель разработки. Чтобы добавить поддержку новых систем, нужно писать новые модули. [...] OPA полностью построен на REST. По сути, всё является конфигурацией. [...] Мы можем создать 80% абстракции, а остальные сами допишут всё, что нужно, через конфиг!<\/p>\n<\/blockquote>\n<p>Это сравнение описывает переход от традиционной, монолитной архитектуры к современной, микросервисной. Однако история неполная без третьего ключевого элемента — OPAL, который решает фундаментальную проблему OPA при масштабировании.<\/p>\n<p>Давайте рассмотрим все три компонента по порядку.<\/p>\n<h5>1. “Классический” подход: Apache Ranger<\/h5>\n<p>Apache Ranger — это зрелая и мощная система для централизованного управления политиками безопасности в экосистеме больших данных (Hadoop, Hive, Kafka и т.д.).<\/p>\n<ul>\n<li><b>Как это работает:<\/b> Ranger работает по принципу “сервер + плагины”. Центральный сервер хранит все политики доступа. В каждую защищаемую систему (например, в Hive) устанавливается специальный плагин, который периодически опрашивает сервер Ranger, скачивает актуальные политики и кэширует их для быстрой проверки доступа.<\/li>\n<\/ul>\n<ul>\n<li><b>Сильные стороны:<\/b>\n<ul>\n  <li><b>Централизация:<\/b> Единый центр для аудита и управления доступом.<\/li>\n  <li><b>Мощность:<\/b> Глубокая интеграция с поддерживаемыми системами (например, безопасность на уровне колонок в Hive).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li><b>Слабые стороны (те самые “фиксированные модели разработки”):<\/b>\n<ul>\n  <li><b>Негибкость:<\/b> Поддержка новой системы, не входящей в стандартный набор, требует написания плагина на Java, компиляции и развертывания новой версии Ranger. Это медленно и требует узкой экспертизы.<\/li>\n  <li><b>“Бутылочное горлышко”:<\/b> Все изменения проходят через центральную команду, что замедляет продуктовые команды.<\/li>\n  <li><b>Не для микросервисов:<\/b> Этот подход плохо подходит для динамичного мира микросервисов, где новые сервисы появляются каждый день.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><b>Аналогия:<\/b> Ranger — это как служба безопасности крупного завода, которая работает только со стандартными станками этого завода. Если вы покупаете новый станок из-за границы, вам нужно написать для службы безопасности целую новую инструкцию и переобучить персонал.<\/p>\n<h5>2. “Гибкий” подход: Open Policy Agent (OPA)<\/h5>\n<p>OPA — это универсальный движок политик с открытым исходным кодом. Его философия прямо противоположна Ranger. OPA ничего не знает о тех, кого он защищает.<\/p>\n<ul>\n<li><b>Как это работает:<\/b>\n<ol start=\"1\">\n  <li>Ваш сервис, получив запрос, формирует JSON-документ с контекстом (`{“user”: “alice”, “action”: “read”, “resource”: “document”}`).<\/li>\n  <li>Он отправляет этот JSON в OPA через простой REST API-вызов.<\/li>\n  <li>OPA применяет к этому JSON’у правила, написанные на языке <b>Rego<\/b>, и мгновенно возвращает решение: `allow` или `deny`.<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<ul>\n<li><b>Сильные стороны:<\/b>\n<ul>\n  <li><b>Универсальность:<\/b> OPA может управлять доступом к чему угодно — микросервисам, Kubernetes, конвейерам CI\/CD, базам данных.<\/li>\n  <li><b>Policy-as-Code:<\/b> Политики на Rego — это код. Их можно хранить в Git, версионировать, тестировать и автоматически развертывать.<\/li>\n  <li><b>Децентрализация:<\/b> OPA обычно развертывается как “сайдкар”-контейнер рядом с каждым экземпляром сервиса, что обеспечивает низкую задержку и высокую отказоустойчивость.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li><b>Проблема, которую OPA создает:<\/b>  <br \/>\nПредставьте, у вас 500 микросервисов, и рядом с каждым работает свой экземпляр OPA. Возникают вопросы:<\/li>\n\n<ul>\n  <li>Как доставить обновление политики во все 500 экземпляров OPA одновременно?<\/li>\n  <li>Откуда OPA возьмет данные для принятия решений (например, список ролей пользователя или владельцев документа)? Если каждый из 500 экземпляров OPA будет сам ходить в базу данных, это создаст колоссальную нагрузку.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Здесь на сцену выходит OPAL.<\/p>\n<h5>3. “Связующее звено”: OPAL (Open Policy Administration Layer)<\/h5>\n<p>OPAL — это не еще один движок политик. Это <b>административный слой реального времени для OPA<\/b>. Его единственная задача — поддерживать политики и данные в ваших OPA-агентах в актуальном состоянии.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-210.png\" width=\"1997\" height=\"945\" alt=\"\" \/>\n<\/div>\n<ul>\n<li>Как это работает (OPA + OPAL):**\n<ol start=\"1\">\n  <li>Политики (Rego-файлы) хранятся в Git-репозитории. Данные (роли, атрибуты) — в базах данных или API.<\/li>\n  <li><b>OPAL Server<\/b> подписывается на изменения в этих источниках (например, через веб-хуки из Git или топики Kafka).<\/li>\n  <li>Когда происходит изменение (например, разработчик пушит новую политику в Git), OPAL Server получает уведомление.<\/li>\n  <li>Сервер немедленно публикует сообщение об обновлении в легковесный канал (pub\/sub, обычно через WebSockets).<\/li>\n  <li><b>OPAL Clients<\/b>, работающие рядом с каждым OPA, получают это сообщение.<\/li>\n  <li>Клиенты сами скачивают нужные обновления (новую политику из Git, свежие данные из БД) и загружают их в свой локальный OPA.<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<ul>\n<li><b>Что это дает:<\/b>\n<ul>\n  <li><b>Обновления в реальном времени:<\/b> Изменение политики в Git моментально распространяется по всей системе.<\/li>\n  <li><b>Событийная архитектура:<\/b> Нет необходимости постоянно опрашивать источники. Это очень эффективно.<\/li>\n  <li><b>Полное разделение:<\/b> OPA отвечает только за принятие решений. OPAL — за доставку “знаний” для этих решений.<\/li>\n  <li><b>Масштабируемость:<\/b> Эта архитектура легко управляет тысячами OPA-агентов, решая проблему синхронизации.<\/li>\n  <li><b>Завершение истории GitOps:<\/b> Вы управляете доступом ко всей вашей инфраструктуре через `git push`, что полностью соответствует исходному тезису: <b>“всё является конфигурацией”<\/b>. <a href=\"https:\/\/medium.com\/@piyushraw12\/building-enterprise-grade-authorization-with-opal-and-opa-decentralized-policy-management-7bddb315433a\">medium.com<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/telegram-cloud-photo-size-4-5995580363474319391-y.jpg\" width=\"1200\" height=\"1167\" alt=\"\" \/>\n<\/div>\n<hr \/>\n<h4>Итоговое сравнение<\/h4>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td style=\"text-align: center\">Критерий<\/td>\n<td style=\"text-align: center\">Apache Ranger<\/td>\n<td style=\"text-align: center\">OPA (самостоятельно)<\/td>\n<td style=\"text-align: center\">OPA + OPAL (Современный стек)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Архитектура<\/b><\/td>\n<td style=\"text-align: center\">Монолитный сервер + плагины<\/td>\n<td style=\"text-align: center\">Децентрализованный движок политик<\/td>\n<td style=\"text-align: center\">Децентрализованный движок + слой управления реального времени<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Процесс обновления<\/b><\/td>\n<td style=\"text-align: center\">Код -> Компиляция -> Развертывание<\/td>\n<td style=\"text-align: center\">Ручная загрузка политик через API<\/td>\n<td style=\"text-align: center\">`git push` -> Автоматическое распространение<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Гибкость<\/b><\/td>\n<td style=\"text-align: center\">Низкая (только для поддерживаемых систем)<\/td>\n<td style=\"text-align: center\">Очень высокая (универсальный)<\/td>\n<td style=\"text-align: center\">Очень высокая + управляемость в масштабе<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Управление данными<\/b><\/td>\n<td style=\"text-align: center\">Встроено<\/td>\n<td style=\"text-align: center\">Требует самостоятельного решения<\/td>\n<td style=\"text-align: center\">Встроено в архитектуру (OPAL следит за данными)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Масштабируемость<\/b><\/td>\n<td style=\"text-align: center\">Масштабируется, но обновления медленные<\/td>\n<td style=\"text-align: center\">Плохо масштабируется с точки зрения управления<\/td>\n<td style=\"text-align: center\">Отлично масштабируется<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Подход<\/b><\/td>\n<td style=\"text-align: center\">Классический, централизованный<\/td>\n<td style=\"text-align: center\">`Policy-as-Code`, но неполный<\/td>\n<td style=\"text-align: center\">`Policy-as-Code` + `GitOps`, событийно-ориентированный<\/td>\n<\/tr>\n<\/table>\n<h4>Вывод<\/h4>\n<p>Возвращаясь к исходным тезисам, становится ясно, что их автор описывал <b>потенциал OPA<\/b>. Однако чтобы этот потенциал раскрылся в крупной организации, необходима система, которая возьмет на себя рутинную, но критически важную работу по синхронизации.<\/p>\n<ul>\n<li><b>Ranger<\/b> — это мощный, но неповоротливый инструмент из прошлого, идеальный для статичных, гомогенных сред.<\/li>\n<li><b>OPA<\/b> — это гениально простой и гибкий движок, сердце современной авторизации.<\/li>\n<li><b>OPAL<\/b> — это нервная система, которая соединяет это сердце с “мозгом” (Git, базы данных) и позволяет всему организму (вашим микросервисам) реагировать на изменения мгновенно.<\/li>\n<\/ul>\n<p>Современный, масштабируемый и по-настоящему гибкий “слой абстракции”, о котором говорилось в начале, строится именно на связке <b>OPA + OPAL<\/b>. Это позволяет создавать платформу, ценность которой, как и было сказано, “заключается в способности объединять внешние инструменты, команды, данные и процессы”.<\/p>\n<p>Еще было это: <a href=\"https:\/\/gavrilov.info\/all\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac\/\">https:\/\/gavrilov.info\/all\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac\/<\/a><\/p>\n",
            "date_published": "2025-08-29T00:02:28+03:00",
            "date_modified": "2025-09-18T09:12:45+03:00",
            "tags": [
                "IT",
                "Programming",
                "Security"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/image-210.png",
            "_date_published_rfc2822": "Fri, 29 Aug 2025 00:02:28 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "274",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/image-210.png",
                    "https:\/\/gavrilov.info\/pictures\/telegram-cloud-photo-size-4-5995580363474319391-y.jpg"
                ]
            }
        },
        {
            "id": "271",
            "url": "https:\/\/gavrilov.info\/all\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac\/",
            "title": "Эволюция управления доступом: OPA\\OPAL vs FGA, RBAC, ReBAC",
            "content_html": "<p>В разработке программного обеспечения управление доступом пользователей — одна из критически важных задач. От того, кто и какие действия может выполнять в приложении, напрямую зависит его безопасность, функциональность и надежность. Исторически логика авторизации часто была разбросана по всему коду приложения, что приводило к появлению архитектурного антипаттерна, известного как <b>«Большой ком грязи» (Big Ball of Mud)<\/b>.<\/p>\n<p><b>Что такое «Большой ком грязи»?<\/b> Это система, в которой отсутствует четкая архитектура. Логика авторизации, выраженная в бесконечных `if-else` конструкциях, смешивается с бизнес-логикой, обработкой данных и представлением. Такую систему практически невозможно поддерживать, аудировать и масштабировать. Любое изменение в правах доступа требует переписывания кода в разных местах, что увеличивает риск ошибок и уязвимостей.<\/p>\n<p>Современный подход заключается в отделении логики авторизации от основного кода приложения с помощью специализированных инструментов — <b>механизмов политик (Policy Engines)<\/b>. Эти системы позволяют централизованно определять, управлять и применять правила доступа. В предоставленном материале рассматриваются три ведущих механизма: <b>OPA (Open Policy Agent)<\/b>, <b>OpenFGA<\/b> и <b>AWS Cedar<\/b>.<\/p>\n<h5>Основной подход: Политика как код vs. Политика как данные<\/h5>\n<p>Ключевое различие между механизмами политик заключается в их подходе к определению правил. Это разделение можно описать как «управляемые политикой» (policy-driven) и «управляемые данными» data-driven <a href=\"https:\/\/www.permit.io\/blog\/policy-engine-showdown-opa-vs-openfga-vs-cedar.\">https:\/\/www.permit.io\/blog\/policy-engine-showdown-opa-vs-openfga-vs-cedar.<\/a><\/p>\n<ol start=\"1\">\n<li><b>Управляемые политикой (Policy-Driven)<\/b>  <br \/>\nВ этой модели основная логика авторизации описывается в виде кода на специальном декларативном языке. Данные, такие как атрибуты пользователя или ресурса, передаются в механизм во время запроса для принятия решения.<\/li>\n<\/ol>\n<ul>\n<li><b>Cedar (AWS):<\/b> Яркий пример такого подхода. Cedar делает акцент на читаемости и безопасности политик. Политики пишутся так, чтобы их было легко понять и верифицировать. Joy Scharmen из StrongDM отмечает: «Cedar очень ориентирован на политики. Данные проходят через систему как эфемерный ввод, не требуя предопределенной модели данных» <a href=\"https:\/\/www.permit.io\/blog\/policy-engine-showdown-opa-vs-openfga-vs-cedar.\">https:\/\/www.permit.io\/blog\/policy-engine-showdown-opa-vs-openfga-vs-cedar.<\/a> Это идеально для систем, где важна предсказуемость и простота аудита.<\/li>\n<\/ul>\n<ol start=\"2\">\n<li><b>Управляемые данными (Data-Driven)<\/b>  <br \/>\nЗдесь ядром системы являются данные, описывающие *отношения* между субъектами (пользователями) и объектами (ресурсами). Политика — это, по сути, модель, которая интерпретирует эти отношения.<\/li>\n<\/ol>\n<ul>\n<li><b>OpenFGA (на основе Google Zanzibar):<\/b> Этот механизм реализует модель <b>управления доступом на основе отношений (ReBAC)<\/b>. Вы определяете модель (например, «владелец документа может его удалить»), а конкретные связи («пользователь `Alice` является владельцем `document:123`») хранятся как данные <a href=\"https:\/\/www.permit.io\/blog\/opa-cedar-openfga-why-are-policy-languages-trending.\">https:\/\/www.permit.io\/blog\/opa-cedar-openfga-why-are-policy-languages-trending.<\/a> Этот подход чрезвычайно масштабируем для систем со сложными иерархиями и связями, как в Google Docs или социальных сетях.<\/li>\n<\/ul>\n<ol start=\"3\">\n<li><b>Гибридный подход<\/b>  <br \/>\nНекоторые механизмы поддерживают оба подхода.<\/li>\n<\/ol>\n<ul>\n<li><b>OPA (Open Policy Agent):<\/b> OPA является универсальным механизмом общего назначения <a href=\"https:\/\/www.permit.io\/blog\/policy-engines.\">https:\/\/www.permit.io\/blog\/policy-engines.<\/a> Он позволяет как загружать данные и политики в виде «пакетов» (bundles), так и получать их динамически во время выполнения. Это дает максимальную гибкость, но требует более тщательного проектирования архитектуры.<\/li>\n<\/ul>\n<h5>Архитектурные модели развертывания<\/h5>\n<p>Выбор между централизованной и децентрализованной архитектурой напрямую влияет на производительность и отказоустойчивость.<\/p>\n<ul>\n<li><b>Централизованная модель:<\/b> Все сервисы обращаются к единому центральному сервису авторизации.\n<ul>\n  <li><b>Плюсы:<\/b> Единый источник правды, консистентность решений.<\/li>\n  <li><b>Минусы:<\/b> Может стать узким местом (bottleneck) и единой точкой отказа.<\/li>\n<\/ul>\n<\/li>\n<li><b>Децентрализованная модель:<\/b> Механизм политик разворачивается как «сайдкар» (sidecar) рядом с каждым экземпляром приложения.\n<ul>\n  <li><b>Плюсы:<\/b> Минимальная задержка (latency), высокая отказоустойчивость.<\/li>\n  <li><b>Минусы:<\/b> Требует синхронизации политик и данных между всеми экземплярами.<\/li>\n<\/ul>\n<\/li>\n<li><b>Гибридная модель:<\/b> «Управляй централизованно, авторизуй локально». Политики и данные управляются из центра, но доставляются на децентрализованные механизмы для локального принятия решений.<\/li>\n<\/ul>\n<p>Для решения проблемы синхронизации в децентрализованных моделях существуют инструменты, такие как <b>OPAL (Open Policy Administration Layer)<\/b>. OPAL работает поверх OPA, Cedar и OpenFGA, обнаруживая изменения в политиках и данных в реальном времени и доставляя обновления агентам <a href=\"https:\/\/docs.opal.ac.\">https:\/\/docs.opal.ac.<\/a><\/p>\n<h5>Сравнение механизмов: плюсы и минусы<\/h5>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td style=\"text-align: center\">Механизм<\/td>\n<td style=\"text-align: center\">Описание<\/td>\n<td style=\"text-align: center\">Плюсы<\/td>\n<td style=\"text-align: center\">Минусы<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\">:---<\/td>\n<td style=\"text-align: center\">:---<\/td>\n<td style=\"text-align: center\">:---<\/td>\n<td style=\"text-align: center\">:---<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>OPA (Open Policy Agent)<\/b><\/td>\n<td style=\"text-align: center\">Универсальный механизм общего назначения, использующий язык <b>Rego<\/b>.<\/td>\n<td style=\"text-align: center\"><b>Гибкость:<\/b> Поддерживает RBAC, ABAC, ReBAC. Может использоваться не только для авторизации.<br><b>Экосистема:<\/b> Зрелый проект CNCF с огромным сообществом и инструментарием.<br><b>Адаптивность:<\/b> Может работать в stateful и stateless режимах, быть централизованным или децентрализованным.<\/td>\n<td style=\"text-align: center\"><b>Сложность:<\/b> Язык Rego имеет порог вхождения.<br><b>Требует дисциплины:<\/b> Гибкость может привести к усложнению, если не планировать архитектуру тщательно.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>OpenFGA<\/b><\/td>\n<td style=\"text-align: center\">Специализированный механизм, основанный на Google Zanzibar. Реализует <b>ReBAC<\/b>.<\/td>\n<td style=\"text-align: center\"><b>Масштабируемость:<\/b> Идеален для систем с большим количеством пользователей и сложными отношениями между объектами.<br><b>Производительность:<\/b> Проверенная модель, оптимизированная для быстрых проверок разрешений.<br><b>Четкая модель:<\/b> Фокусируется на одной задаче и делает ее хорошо.<\/td>\n<td style=\"text-align: center\"><b>Узкая специализация:<\/b> Менее интуитивен для простых сценариев RBAC или ABAC <a href=\"https:\/\/www.permit.io\/blog\/opa-cedar-openfga-why-are-policy-languages-trending\">https:\/\/www.permit.io\/blog\/opa-cedar-openfga-why-are-policy-languages-trending<\/a><br><b>Синхронизация данных:<\/b> Основная сложность — поддерживать граф отношений в актуальном состоянии.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>AWS Cedar<\/b><\/td>\n<td style=\"text-align: center\">Механизм, ориентированный на безопасность, читаемость и формальную верификацию политик.<\/td>\n<td style=\"text-align: center\"><b>Простота и читаемость:<\/b> Политики легко писать и аудировать.<br><b>Безопасность:<\/b> Встроенные средства верификации для проверки корректности политик.<br><b>Низкий порог вхождения:<\/b> Интуитивно понятен для команд, новых в этой области.<\/td>\n<td style=\"text-align: center\"><b>Ограниченная гибкость:<\/b> В первую очередь предназначен для авторизации и менее гибок, чем OPA.<br><b>Stateless-ориентированность:<\/b> Модель, где все данные передаются с запросом, может не подходить для всех сценариев.<\/td>\n<\/tr>\n<\/table>\n<h5>Итог: нет “победителя”, есть правильный инструмент<\/h5>\n<p>Как было подчеркнуто в дискуссии на KubeCon, «победителя нет». Выбор механизма политик полностью зависит от конкретного случая использования:<\/p>\n<ul>\n<li><b>Если у вас сложная система с множеством взаимосвязанных разрешений<\/b> (например, совместное редактирование документов, социальная сеть), <b>OpenFGA<\/b> — ваш выбор.<\/li>\n<li><b>Если вам нужен универсальный инструмент<\/b> для управления политиками в разных частях стека (Kubernetes, CI\/CD, микросервисы) и ваша команда готова изучить новый язык, <b>OPA<\/b> предоставит максимальную гибкость.<\/li>\n<li><b>Если ваша главная цель — простая, безопасная и легко проверяемая авторизация<\/b> в приложении, и вы цените читаемость политик, <b>Cedar<\/b> будет отличным стартом.<\/li>\n<\/ul>\n<p>Переход от «большого кома грязи» к внешним механизмам политик — это шаг к созданию более надежных, безопасных и поддерживаемых систем. Благодаря таким проектам, как OPA, OpenFGA, Cedar и инструментам вроде OPAL, разработчики получают мощные средства для построения современных систем управления доступом <a href=\"https:\/\/www.permit.io\/blog\/introduction-to-opal\">https:\/\/www.permit.io\/blog\/introduction-to-opal<\/a><\/p>\n<p>OPA + OPAL == 💜<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac.png\" width=\"2152\" height=\"1156\" alt=\"\" \/>\n<\/div>\n<p><a href=\"https:\/\/github.com\/permitio\/opal?tab=readme-ov-file\">https:\/\/github.com\/permitio\/opal?tab=readme-ov-file<\/a><\/p>\n<p>Спойлер ...<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Screenshot-from-2025-08-22-12-22-33.png\" width=\"1047\" height=\"252\" alt=\"\" \/>\n<\/div>\n",
            "date_published": "2025-08-19T23:44:00+03:00",
            "date_modified": "2025-08-22T12:23:07+03:00",
            "tags": [
                "Security"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac.png",
            "_date_published_rfc2822": "Tue, 19 Aug 2025 23:44:00 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "271",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/evolyuciya-upravleniya-dostupom-opa-opal-vs-fga-rbac-rebac.png",
                    "https:\/\/gavrilov.info\/pictures\/Screenshot-from-2025-08-22-12-22-33.png"
                ]
            }
        },
        {
            "id": "130",
            "url": "https:\/\/gavrilov.info\/all\/platforma-zaschity-dannyh-principy-i-praktika\/",
            "title": "Платформа защиты данных: принципы и практика",
            "content_html": "<p>Перевод: <a href=\"https:\/\/sanjmo.medium.com\/drowning-in-data-a-data-security-platform-dsp-is-your-life-raft-92be7cdc9e66\">https:\/\/sanjmo.medium.com\/drowning-in-data-a-data-security-platform-dsp-is-your-life-raft-92be7cdc9e66<\/a><\/p>\n<p>В январе 2024 года Gartner опубликовал свой первый рыночный гид по платформам защиты данных, признав растущую важность объединения контролей безопасности данных, бизнес-логики и детализированной авторизации. Эти ключевые черты позволяют бизнесу раскрыть потенциал всех своих информационных активов и использовать их для принятия решений.<\/p>\n<p>Защита данных не является новым открытием, а давно признанной необходимостью. В прошлом эти меры внедрялись как второстепенные и изолированные, что затрудняло своевременный и безопасный доступ к корпоративным данным. Однако сейчас организации делают защиту данных приоритетом и внедряют её структурированным образом. Неудивительно, что Gartner сообщает о 70-процентном росте звонков, связанных с защитой данных, между 2021 и 2022 годами.<\/p>\n<p>Хотя ChatGPT открыл потенциал ИИ, трансформируя наши организации, впереди еще большая возможность в виде персонализированной ИИ-стека. Этот стек объединяет крупные языковые модели и корпоративные данные, позволяя получать результаты, основанные на реальной бизнес-информации.<\/p>\n<p>С этой мощью компании могут действительно использовать скрытый потенциал огромных объемов структурированных и неструктурированных данных. И, базируя результаты на тщательно отобранных корпоративных данных, они могут уменьшить количество неправильных выводов и повысить доверие к результатам генеративной работы ИИ.<\/p>\n<p>Однако для достижения этого состояния просветления необходимо сначала убедиться, что соблюдены корпоративные правила безопасности и все соответствующие нормативные требования. Это требует сложной платформы защиты данных (DSP).<\/p>\n<p>Компоненты платформы защиты данных (DSP)<br \/>\nКак тормоза у автомобиля, защита данных предназначена не для замедления, а для безопасного ускорения с доверием и уверенностью. Они созданы, чтобы предотвращать как намеренное, так и случайное использование инфраструктуры данных. Цель состоит в том, чтобы обеспечить доступ к нужным данным для нужных людей в нужное время, чтобы принимать бизнес-решения и получать конкурентное преимущество.<\/p>\n<p>Надежная платформа защиты данных состоит из трёх основных элементов, приведённых ниже.<\/p>\n<p>Элементы платформы защиты данных (DSP)<br \/>\nОбнаружение и наблюдение<br \/>\nПервая итерация больших данных, начатая Hadoop, превратила озера данных в болота данных из-за недостаточного понимания данных. В стремлении сделать данные доступными для анализа был пропущен критический этап их понимания, включая чувствительные данные.<\/p>\n<p>Современная DSP должна иметь возможность подключаться к исходным системам и определять характер данных. Чувствительность данных скрыта в контексте самих данных. Когда чувствительные данные обнаружены, их необходимо пометить в соответствии с корпоративными правилами безопасности и применимыми нормативными требованиями. Эти данные могут включать личную идентификационную информацию (PII), личную медицинскую информацию (PHI), финансовые данные, интеллектуальную собственность или производственные секреты.<\/p>\n<p>Ваша DSP должна уметь подключаться ко всем соответствующим источникам данных и выявлять чувствительные данные, используя несколько подходов:<\/p>\n<ul>\n<li>Профилирование исходных данных: сканирование и профилирование данных часто использует выборку, но должно иметь возможность сканировать полный набор данных. Однако это может создать нагрузку на операционные системы. Этот вариант требует разрешений для доступа к исходным данным.<\/li>\n<li>Профилирование ответов: чтобы преодолеть некоторые из вышеупомянутых барьеров, можно профилировать и классифицировать ответы. Например, можно выявлять электронные письма, номера социального страхования и другую личную информацию.<\/li>\n<li>Пометка данных может быть ручной, однако чаще всего используется сложные алгоритмы машинного обучения. Этот процесс должен быть непрерывным, так как данные меняются в реальном времени. Таким образом, в вашей DSP необходимы возможности наблюдения.<\/li>\n<\/ul>\n<p>Определение политики<br \/>\nСледующий шаг – возможность определения детализированных политик и правил по защите данных, таких как авторизация и шифрование. Ответственные за данные должны иметь возможность интуитивно и с самообслуживанием создавать политики управления, а не использовать старые подходы, распространенные в системах управления идентификацией и доступом. Наиболее распространенный подход – использование интерфейса с выпадающими опциями. Например, могут быть опции для шифрования или маскирования данных или тегов.<\/p>\n<p>Новые системы позволяют автоматически определять и находить политики. Автоматизация создания политик также помогает, когда пользователь уходит из компании и все соответствующие политики должны быть удалены. Для достижения этой способности важно, чтобы DSP интегрировалась с остальной инфраструктурой управления данными, такой как каталоги данных. Например, интеграция с каталогом данных позволяет пользователям находить данные, видеть, что доступно, запрашивать доступ, фиксировать намерения и согласие, а затем предоставлять доступ. Эти продукты должны сохранять историю доступа и журналы аудита.<\/p>\n<p>Принуждение к соблюдению политики<br \/>\nЗаключительный этап – это выполнение политик безопасности данных с минимальными накладными расходами и задержками. Для назначения прав доступа в зависимости от роли пользователя в проекте следует использовать контроль доступа на основе ролей (RBAC). Для предоставления доступа на основе комбинации атрибутов пользователя, атрибутов данных и атрибутов окружения следует использовать контроль доступа на основе атрибутов (ABAC), обеспечивая более детализированный контроль.<\/p>\n<p>Некоторые важные факторы при исполнении политики включают:<\/p>\n<ul>\n<li>Согласованность: политики безопасности должны применяться к данным независимо от того, где они хранятся – в облачных хранилищах данных, операционных системах, хранилищах объектов или озерах данных.<\/li>\n<li>Низкую задержку и масштабируемость: накладные расходы на безопасность данных должны быть минимальными для запросов. Они также должны масштабироваться с ростом нагрузки.<\/li>\n<li>Динамичность: предпочтительнее ABAC, так как он динамический и адаптируется с изменением окружения пользователя.<\/li>\n<li>Адаптивность: продукт для защиты данных должен быть прозрачным для конечных пользователей. В идеале пользователь должен обращаться к конечной точке или использовать API, который автоматически применяет политики безопасности и не требует изменений в схеме или запросах.<\/li>\n<li>Развертывание: современные продукты безопасности развёртываются либо как SaaS-инструменты, либо в частных облаках, управляемых с помощью Kubernetes.<\/li>\n<\/ul>\n<p>Бесшовное принуждение к соблюдению политики помогает построить доверие к данным и увеличить их полезность. Это позволяет организациям расширять возможности обмена данными с потребителями, такими как развертывание маркетплейсов данных.<\/p>\n",
            "date_published": "2024-06-09T23:46:23+03:00",
            "date_modified": "2024-06-09T23:46:14+03:00",
            "tags": [
                "Data",
                "Security"
            ],
            "_date_published_rfc2822": "Sun, 09 Jun 2024 23:46:23 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "130",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "61",
            "url": "https:\/\/gavrilov.info\/all\/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostey\/",
            "title": "Как хакеры ломают кошельки: шесть главных уязвимостей",
            "content_html": "<p>Оригинал статьи тут: <a href=\"https:\/\/forklog.com\/exclusive\/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostej\">https:\/\/forklog.com\/exclusive\/kak-hakery-lomayut-koshelki-shest-glavnyh-uyazvimostej<\/a><\/p>\n<p>Приватный ключ в большинстве блокчейнов представляет собой строку из 256 бит: на подбор такого пароля к конкретному адресу уйдут миллионы лет работы современных компьютеров.<\/p>\n<p>Однако криптокошельки все же уязвимы к хакерским атакам — из-за багов в приложениях и ошибок пользователей. Рассказываем о шести способах взлома и объясняем, как обезопасить средства от кражи.<\/p>\n<ol start=\"1\">\n<li>Weak Address — уязвимые ключи<\/li>\n<\/ol>\n<p>Из-за бага в генераторе случайных чисел (ГСЧ) кошелек может создать приватный ключ лишь с несколькими случайными байтами. В идеале приложение работает так:<\/p>\n<p>Генерирует случайное число заданной длины.<br \/>\nПреобразует его в короткий формат ключа соответствующего блокчейна.<br \/>\nГенерирует публичный адрес из ключа.<br \/>\nВ этом случае число fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364110 преобразуется в ключ 5Km2kuu7vtFDPpxywn4u3NLpbr5jKpTB3jsuDU2KYEqeoQJAair, который управляет адресом 1CaZUpjd7VmsyWDFrk9WG9nTYMLcLLvvCw.<\/p>\n<p>Но иногда ГСЧ допускает ошибку и генерирует строку с большим количеством нулей вроде 0000000000000000000000000000000000000000ffa3cafff0000000000000000 вместо действительно случайного числа. Хакеры называют такие кошельки Weak Addresses.<\/p>\n<p>Злоумышленники создают ботов. Их алгоритмы регулярно проверяют балансы слабых адресов в сетях биткоина и Ethereum. Если пользователь генерирует такой адрес и отправляет на него криптовалюту, бот сразу же ее ворует.<\/p>\n<p>Как защититься: после создания кошелька проверьте, действительно ли символы в нем случайны. Используйте инструменты с открытым исходным кодом вроде Swippcore для конвертации ключа короткого формата в длинный на локальной машине.<\/p>\n<ol start=\"2\">\n<li>Random Vulnerability — извлечение приватных ключей из транзакций<\/li>\n<\/ol>\n<p>Биткоины существуют в виде UTXO — неиспользованных выходов. При отправке средств кошелек собирает их на нужную сумму и подписывает транзакцию комбинацией приватного ключа и случайного числа — nonce.<\/p>\n<p>Из-за бага ГСЧ приложение может подписать разные операции одинаковыми nonce. Если злоумышленники сопоставят и дешифруют подписи таких транзакций, то смогут извлечь приватные ключи.<\/p>\n<p>Этот метод называется Random Vulnerability. С его помощью хакеры взломали более двух тысяч кошельков на сумму 484 BTC.<\/p>\n<p>Согласно исследованию компании Kudelski Security, уязвимость также встречается в кошельках Ethereum и EVM-совместимых сетей.<\/p>\n<p>Как защититься: вовремя обновлять приложения кошельков, в том числе Bitcoin Core и его аналоги для других блокчейнов.<\/p>\n<ol start=\"3\">\n<li>Weak Brainwallet — генерация ключей  из неслучайных данных<\/li>\n<\/ol>\n<p>Brainwallet — способ создания приватного ключа на базе пользовательской фразы вместо случайного числа. Ее легко можно запомнить, а значит буквально «хранить в голове».<\/p>\n<p>Зачастую пользователи генерируют ключи из единичных слов, очевидных комбинаций вроде 12341234, телефонных номеров или цитат из фильмов. Хакеры пользуются человеческой предсказуемостью: они создают ключи из популярных или утекших паролей, а затем выводят криптовалюты с соответствующих кошельков. Таким образом с 2009 года злоумышленники взломали более 19 000 биткоин-кошельков и украли как минимум 4000 BTC.<\/p>\n<p>Как хакеры ломают кошельки: шесть главных уязвимостей<br \/>\nПримеры взломанных кошельков, владельцы которых сгенерировали ключи из распространенных фраз. Данные: Privatekeys.<br \/>\nКак защититься: не использовать Brainwallet, в крайнем случае — придумать действительно сложный пароль из строчных и заглавных букв, цифр и спецсимволов.<\/p>\n<p>Рассылки ForkLog: держите руку на пульсе биткоин-индустрии!<\/p>\n<p>Итоги недели<\/p>\n<p>Итоги недели + главные новости по будням<\/p>\n<ol start=\"4\">\n<li>Фишинг — пользователь сам отдает ключ<\/li>\n<\/ol>\n<p>С технической точки зрения самый простой способ получить доступ к кошельку — убедить владельца отправить вам ключ. Для этого злоумышленники представляются сотрудниками службы поддержки бирж и кошельков, известными личностями или специалистами по безопасности.<\/p>\n<p>Например, в феврале 2023 года хакеры отправляли пользователям Trezor фейковые письма от лица компании, в которых сообщали о взломе программного обеспечения кошельков и просили передать сид-фразу для «проверки».<\/p>\n<p>Кроме того, злоумышленники используют инструменты ончейн-аналитики атак на кошельки биткоин-китов — известных личностей, менеджеров блокчейн-проектов и криптоинфлюэнсеров. Они пишут персонализированные письма и связываются с жертвами по личным каналам коммуникаций.<\/p>\n<p>Как защититься: ни в коем случае не отправлять приватный ключ или сид-фразу кому бы то ни было.<\/p>\n<ol start=\"5\">\n<li>Ключи в публичном доступе — мониторинг GitHub<\/li>\n<\/ol>\n<p>Разработчики блокчейн-приложений и смарт-контрактов иногда используют личные кошельки для проверки работоспособности кода. Они могут случайно оставить ключи в файлах при публикации проектов на хостинговых сервисах.<\/p>\n<p>Хакеры отслеживают обновления и загрузки репозиториев на GitHub, Pastebin и других популярных платформах для хранения текстовых заметок. Они проверяют строки, которые начинаются с «5» (биткоин-ключи в формате WIF), содержат слова из словаря сид-фраз или совпадают с длиной закрытого ключа.<\/p>\n<p>Как защититься: не хранить пароли на компьютере в незашифрованных файлах, не использовать личный кошелек в рабочих целях.<\/p>\n<ol start=\"6\">\n<li>Скам-сайты — генерация скомпрометированных ключей<\/li>\n<\/ol>\n<p>С 2019 года хакеры используют генераторы онлайн-кошельков в качестве инструмента взлома. Такие сервисы могут выдавать одни и те же ключи разным пользователям или содержать уязвимости для их перехвата.<\/p>\n<p>Так, в июле 2023 года пользователь r\/jdmcnair заявил о краже $3000 в биткоине из бумажного кошелька, который он сгенерировал в онлайн-сервисе.<\/p>\n<p>Как защититься: не пользоваться веб-сайтами — создавать адреса только в аппаратных устройствах или приложениях кошельков.<\/p>\n<p>Как создать безопасный кошелек<\/p>\n<p>Приватные ключи безопаснее большинства паролей, но и они могут стать уязвимыми из-за ошибок в приложениях и человеческого фактора.<\/p>\n<p>Чтобы избежать взлома, следуйте инструкции по созданию безопасного биткоин-кошелька:<\/p>\n<p>Не используйте сайты для генерации адресов — только аппаратные кошельки и приложения.<br \/>\nНе создавайте ключи из фраз и паролей, которые можете запомнить: они уязвимее комбинаций, созданных ГСЧ.<br \/>\nПосле генерации кошелька проверьте, действительно ли символы в нем случайны. Если более половины символов ключа — нули, он уязвим для брутфорса.<br \/>\nКроме того, важно не использовать личные криптовалютные адреса для разработки Web3-приложений регулярно обновлять кошелек.<\/p>\n<p>Помните: приватные ключи нельзя отправлять третьим лицам, что бы они ни говорили.<\/p>\n",
            "date_published": "2023-08-10T21:10:23+03:00",
            "date_modified": "2023-08-10T21:10:13+03:00",
            "tags": [
                "blockchain",
                "Security"
            ],
            "_date_published_rfc2822": "Thu, 10 Aug 2023 21:10:23 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "61",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        }
    ],
    "_e2_version": 4171,
    "_e2_ua_string": "Aegea 11.4 (v4171e)"
}