Зачем нужен Guardrails Filter: проблема утечки данных в LLM
Корпоративное использование LLM растёт экспоненциально. По данным внутреннего аудита Cloud.ru за 2025 год, 68% сотрудников компаний, использующих публичные AI-сервисы, хотя бы раз отправляли в промптах конфиденциальную информацию: номера договоров, паспортные данные, фрагменты финансовой отчётности. Проблема не в злом умысле, а в удобстве: скопировать текст из CRM и вставить в чат с моделью быстрее, чем обезличивать его вручную.
Стандартные методы защиты не справляются. Клиентская обфускация требует дисциплины от каждого сотрудника и ломается при обновлении UI. Прокси уровня L7 видят HTTPS-трафик как зашифрованный поток и не могут анализировать содержимое. Результат: данные утекают, а DLP-системы молчат.
Guardrails Filter от Cloud.ru решает эту проблему на уровне инфраструктуры. Это опенсорс-инструмент, который работает как обратный прокси между клиентом и LLM-провайдером, перехватывает запросы и ответы, находит в них конфиденциальные данные по 260 встроенным правилам и маскирует их на лету. Никаких модификаций кода приложений, никаких клиентских плагинов. Фильтр встраивается в трафик прозрачно и обрабатывает даже потоковые SSE-ответы и tool-call вызовы, которые пропускают большинство аналогов.
Если вы проектируете корпоративную AI-архитектуру, вопрос безопасности данных встаёт на уровне выбора инструментов оркестрации и проксирования. В статье про архитектуру AI-агентов мы разбирали, как самописные агенты требуют контроля на каждом этапе пайплайна. Guardrails Filter закрывает критический сегмент этого пайплайна - взаимодействие с LLM.
Архитектура Guardrails Filter: обратный прокси для маскировки данных
Guardrails Filter разворачивается между клиентским приложением и LLM-провайдером. Схема проста: клиент отправляет запрос не напрямую в API модели, а на эндпоинт фильтра. Фильтр принимает запрос, прогоняет его через движок правил маскировки, пересылает очищенный текст в LLM, получает ответ, снова применяет правила и возвращает результат клиенту. Весь процесс занимает миллисекунды, потому что фильтр работает на уровне текста, а не на уровне токенов.
Ключевое отличие от простых прокси - фильтр понимает структуру LLM-взаимодействия. Он парсит JSON-тела запросов в форматах OpenAI API, Anthropic Messages API и других популярных провайдеров, извлекает текстовые поля, применяет маскировку и собирает валидный ответ обратно. Это не тупая замена регулярных выражений в сыром теле запроса, а семантический разбор с сохранением структуры.
Обработка потоковых SSE и tool-call: что это даёт
Server-Sent Events (SSE) - стандартный протокол для стриминга ответов от LLM. Модель генерирует текст чанками, каждый чанк приходит как отдельное событие. Большинство инструментов фильтрации не умеют работать с SSE, потому что чанк может содержать фрагмент конфиденциальных данных, разорванный посередине: первый чанк заканчивается на «паспорт: 4510», второй начинается с «123456». Простое регулярное выражение не найдёт номер паспорта ни в одном из этих фрагментов по отдельности.
Guardrails Filter буферизует SSE-поток, собирает текстовые блоки до семантически полных единиц и только потом применяет правила маскировки. Это критично для production-сред, где стриминг используют для улучшения UX: пользователь видит, как ответ появляется постепенно, а не ждёт полной генерации.
Tool-call вызовы - вторая уникальная возможность. Когда LLM решает вызвать внешнюю функцию, она возвращает структурированный JSON с именем функции и аргументами. В аргументах могут оказаться пользовательские данные, которые модель извлекла из контекста. Guardrails Filter парсит tool-call блоки, проверяет значения аргументов и маскирует их до попадания во внешнюю систему. Это закрывает вектор атаки, который часто игнорируют: утечку данных через вызовы API к внутренним сервисам.
Проблема безопасности AI-агентов, которые активно используют tool-call, подробно разобрана в нашем анализе инцидента с Fable: агент без sandbox-изоляции выполнял автономный пентест, и отсутствие guard rails привело к блокировке. Guardrails Filter - это как раз тот уровень защиты, который предотвращает передачу чувствительных данных в инструменты агента.
260 встроенных правил маскировки: покрытие российских и международных форматов ПДн
Фильтр поставляется с готовой библиотекой из 260 правил, покрывающих российские и международные форматы персональных данных. Российский блок включает: паспортные данные (серия и номер в форматах XX XX XXXXXX и XXXX XXXXXX), ИНН (10-значный для юрлиц и 12-значный для физлиц), СНИЛС (XXX-XXX-XXX XX), номера телефонов (+7 и 8), адреса электронной почты, номера банковских карт (16-значные с проверкой алгоритма Луна), ОГРН и ОГРНИП.
Международный блок покрывает: email-адреса, номера кредитных карт (Visa, Mastercard, Amex), Social Security Numbers (США), National Insurance Numbers (Великобритания), IBAN (европейские банковские счета), IP-адреса, MAC-адреса. Каждое правило можно включать и отключать независимо через конфигурационный файл.
Пример конфигурации для активации только российских форматов:
rules:
- name: passport_russian
enabled: true
mask_char: "*"
preserve_length: true
- name: inn
enabled: true
- name: snils
enabled: true
- name: phone_russian
enabled: true
- name: email
enabled: false # отключаем, если email считаем допустимым
Для нестандартных форматов Guardrails Filter поддерживает добавление собственных правил через регулярные выражения. Правило задаётся в YAML-файле: имя, паттерн, символ маскировки и флаг сохранения длины. После добавления правило сразу применяется ко всем запросам без перезагрузки сервиса - фильтр подхватывает изменения конфигурации на лету.
Развертывание Guardrails Filter: пошаговое руководство
Фильтр поставляется как Docker-образ и поддерживает два режима развертывания: standalone-сервис для быстрого старта и интеграцию с Envoy через ext_proc-сайдкар для production-сред с высокими требованиями к отказоустойчивости.
Standalone-развертывание через Docker
Самый быстрый способ запустить фильтр - одна команда:
docker run -d \
--name guardrails-filter \
-p 8080:8080 \
-e LLM_ENDPOINT=https://api.openai.com \
-e LLM_API_KEY=sk-your-key \
-e STORAGE_BACKEND=memory \
-e GHOST_MODE=true \
cr.cloud.ru/guardrails-filter:latest
Параметры:
LLM_ENDPOINT- URL LLM-провайдера, к которому фильтр будет проксировать запросыLLM_API_KEY- API-ключ для аутентификации (фильтр пробрасывает его в заголовках)STORAGE_BACKEND- тип хранилища: memory, redis или postgresGHOST_MODE- режим наблюдения без блокировки трафика (true/false)
После запуска клиентское приложение перенаправляется на http://localhost:8080 вместо прямого обращения к LLM-провайдеру. Фильтр принимает запросы в формате OpenAI API и совместимых, поэтому замена эндпоинта происходит без изменения кода - достаточно поменять base_url в клиентской библиотеке.
Интеграция с Envoy через ext_proc-сайдкар
Для production-сред с service mesh Guardrails Filter интегрируется с Envoy через протокол ext_proc (External Processor). В этой схеме Envoy обрабатывает весь входящий трафик и делегирует проверку содержимого внешнему процессору - фильтру. Сайдкар-архитектура разделяет ответственность: Envoy отвечает за маршрутизацию и TLS, фильтр - за анализ и маскировку данных.
Пример конфигурации Envoy для подключения фильтра:
static_resources:
listeners:
- name: main
address:
socket_address:
address: 0.0.0.0
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: llm_backend
http_filters:
- name: envoy.filters.http.ext_proc
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
grpc_service:
envoy_grpc:
cluster_name: guardrails_filter
processing_mode:
request_header_mode: SEND
response_header_mode: SEND
request_body_mode: BUFFERED
response_body_mode: BUFFERED
- name: envoy.filters.http.router
clusters:
- name: llm_backend
connect_timeout: 5s
type: STRICT_DNS
load_assignment:
cluster_name: llm_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.openai.com
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
- name: guardrails_filter
connect_timeout: 1s
type: STRICT_DNS
http2_protocol_options: {}
load_assignment:
cluster_name: guardrails_filter
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: guardrails-filter
port_value: 50051
Преимущества этого подхода: независимое масштабирование фильтра и Envoy, автоматический failover при отказе процессора, централизованное управление политиками безопасности для всех LLM-эндпоинтов. Envoy буферизует тело запроса и ответа, отправляет их фильтру на анализ, получает решение и только потом пропускает трафик дальше.
Настройка хранилища: память, Redis, PostgreSQL и шифрование
Guardrails Filter использует хранилище для сохранения состояния: кэша правил, логов срабатываний, метрик. Доступны три бэкенда, выбор зависит от требований к производительности и надёжности.
| Бэкенд | Задержка | Персистентность | Сценарий |
|---|---|---|---|
| memory | < 1 мс | Нет (данные теряются при перезапуске) | Тестирование, Ghost Mode, разработка |
| Redis | 1-3 мс | Опционально (RDB/AOF) | Production со средними нагрузками, когда важна скорость |
| PostgreSQL | 3-10 мс | Полная (ACID) | Production с высокими требованиями к надёжности и аудиту |
Для всех бэкендов включается шифрование хранилища. Фильтр использует AES-256-GCM для шифрования данных перед записью в Redis или PostgreSQL. Ключ шифрования задаётся через переменную окружения ENCRYPTION_KEY и никогда не попадает в логи. Если ключ не задан, фильтр откажется стартовать с персистентным бэкендом - это защита от случайного сохранения чувствительных данных в открытом виде.
Пример конфигурации для production с PostgreSQL и шифрованием:
STORAGE_BACKEND=postgres
POSTGRES_DSN=postgres://user:pass@postgres:5432/guardrails
ENCRYPTION_KEY=base64-encoded-32-byte-key
STORAGE_TTL=72h # автоочистка логов старше 72 часов
Тестирование без риска: режим Ghost Mode
Ghost Mode - режим наблюдения, при котором фильтр анализирует трафик, логирует все срабатывания правил, но не изменяет запросы и ответы. Трафик проходит через фильтр прозрачно, как через обычный прокси, а в логах накапливается статистика: какие правила срабатывают, на каких эндпоинтах, с какой частотой.
Активация одной переменной окружения: GHOST_MODE=true. После включения фильтр пишет структурированные логи в формате JSON:
{
"timestamp": "2026-07-22T14:31:05Z",
"rule": "passport_russian",
"action": "detected",
"endpoint": "/v1/chat/completions",
"field": "messages[0].content",
"masked_preview": "паспорт: **** ******",
"client_ip": "10.0.1.45"
}
Ghost Mode решает главный страх при внедрении: «фильтр сломает продакшен». Вы запускаете фильтр в режиме наблюдения на неделю, собираете статистику, видите реальную картину утечек и только потом включаете активную маскировку. За это время можно точно настроить правила: отключить ложные срабатывания, добавить исключения для тестовых данных, проверить влияние на задержку.
Мониторинг и метрики: интеграция с Prometheus и Grafana
Guardrails Filter экспонирует метрики в формате Prometheus на эндпоинте /metrics. Основные метрики:
guardrails_requests_total- общее количество обработанных запросов (счётчик)guardrails_rules_triggered- количество срабатываний правил маскировки с лейблами rule и action (detected/masked)guardrails_request_duration_seconds- гистограмма задержек обработки запросовguardrails_sse_chunks_buffered- количество буферизованных SSE-чанковguardrails_storage_operations_total- операции с хранилищем с лейблами backend и status
Пример конфигурации Prometheus для сбора метрик:
scrape_configs:
- job_name: 'guardrails-filter'
scrape_interval: 15s
static_configs:
- targets: ['guardrails-filter:8080']
labels:
environment: 'production'
На основе метрик строится дашборд Grafana: график RPS (request per second), тепловая карта срабатываний правил по времени, перцентили задержек (p50, p95, p99), статус хранилища. Алерты настраиваются на резкий рост срабатываний конкретного правила (потенциальная утечка) или падение доступности фильтра.
Для observability сложных AI-систем метрик прокси недостаточно - нужно видеть полный путь запроса через все компоненты. В статье про трассировку AI-систем мы показывали, как X-Ray восстанавливает картину обработки запроса в распределённых системах. Совместное использование Guardrails Filter и трассировки даёт полный контроль: фильтр закрывает безопасность, трассировка - объяснимость.
Заключение: когда стоит внедрять Guardrails Filter
Guardrails Filter решает конкретную задачу: предотвращает утечку персональных данных через запросы к LLM без модификации кода приложений. Инструмент оправдан в трёх сценариях.
Первый - корпоративные чат-боты и внутренние AI-ассистенты, куда сотрудники копируют данные из рабочих систем. Фильтр ставится между ботом и LLM-провайдером и маскирует всё, что похоже на ПДн, до отправки запроса. Второй - AI-агенты с tool-call, где данные могут утекать через аргументы вызовов функций. Третий - compliance: фильтр обеспечивает требование регуляторов по контролю передачи данных третьим лицам, логируя все срабатывания правил.
Текущие ограничения: фильтр работает на уровне текста и не анализирует изображения или файлы, переданные в мультимодальных запросах. Нагрузочные лимиты зависят от выбранного хранилища - на in-memory бэкенде фильтр держит до 5000 RPS, на PostgreSQL - до 2000 RPS при p99 задержке 10 мс. Для высоконагруженных систем рекомендуется интеграция с Envoy и горизонтальное масштабирование экземпляров фильтра.
Начать лучше всего с Ghost Mode. Поднимите Docker-контейнер, направьте на него тестовый трафик, соберите статистику за неделю. Вы увидите реальный объём конфиденциальных данных, который проходит через ваши LLM-интеграции. Цифры часто удивляют даже команды с выстроенными процессами безопасности. После этого включите активную маскировку - правила уже будут откалиброваны под ваш трафик, а риски для production сведены к нулю.