Когда вы отправляете запрос к LLM-провайдеру через ProxyAPI, содержимое запроса в итоге попадает к внешнему провайдеру модели. В этом содержимом часто оказываются персональные данные пользователей и секреты — номера паспортов, телефоны, email, банковские карты, ИНН, API-ключи, JWT-токены. Ни вы, ни ваш провайдер не всегда можете это контролировать: конечный пользователь вашего приложения просто пишет произвольный текст.
Маскирование трафика от ProxyAPI решает эту задачу на уровне прокси. Сервис анализирует каждый запрос, находит в нём персональные данные и секреты и — в зависимости от выбранного режима — либо блокирует запрос, либо заменяет найденные значения на синтетические до отправки провайдеру. В режиме с демаскированием оригинальные значения автоматически восстанавливаются в ответе модели перед возвратом клиенту — пользователь вашего приложения получает корректный ответ на свой реальный вопрос, а провайдер модели так и не увидит настоящих данных.
Маскирование можно включить для всех или определенных API ключей аккаунта. Сервис доступен бесплатно всем пользователям.
Маскирование поддерживает два режима.
Запрос с обнаруженными персональными данными отклоняется маскированием — провайдеру модели ничего не отправляется. Клиент получает HTTP 400 с перечислением сработавших типов данных в поле detail:
{"detail": "Request blocked by masking policy: email, phone"}
Этот режим подходит, когда само появление персональных данных в трафике — инцидент, а не штатная ситуация.
Найденные значения заменяются на синтетические — правдоподобные, но поддельные. Маскированный запрос уходит провайдеру модели, ответ модели проходит обратный путь: оригинальные значения восстанавливаются в теле ответа до того, как оно вернётся клиенту.
Рассмотрим пошагово на примере.
Шаг 1. Пользователь вашего приложения отправляет запрос:
Составь доверенность на имя Иванов Иван Иванович, паспорт 4509 123456.
Шаг 2. Маскирование обнаруживает номер паспорта и заменяет его на синтетический. Пара «оригинал → замена» запоминается на время обработки этого запроса:
4509 123456 → 7712 998844
Провайдеру модели уходит уже изменённый текст:
Составь доверенность на имя Иванов Иван Иванович, паспорт 7712 998844.
Шаг 3. Модель генерирует ответ, используя тот номер, который видит. Настоящего номера она никогда не видела:
ДОВЕРЕННОСТЬ Я, Иванов Иван Иванович, паспорт 7712 998844, доверяю ...
Шаг 4. Маскирование находит синтетический номер в ответе модели и подставляет обратно оригинал — по той самой паре, которую запомнил на шаге 2. Клиенту вашего приложения возвращается уже восстановленный ответ:
ДОВЕРЕННОСТЬ Я, Иванов Иван Иванович, паспорт 4509 123456, доверяю ...
Пара «оригинал → замена» существует только на время обработки одного запроса: она не сохраняется ни в логах, ни в базе данных, ни в кэше между запросами. В следующем запросе тот же номер паспорта получит другой синтетический номер.
Этот режим — основной. Он сохраняет полезную функциональность для конечного пользователя и одновременно обеспечивает приватность по отношению к провайдеру.
В разделе Маскирование личного кабинета активируйте продукт, выберите режим, отметьте типы данных и — при необходимости — ограничьте действие маскирования выбранными API-ключами. Новые запросы начинают маскироваться сразу после активации.
Маскирование от ProxyAPI распознаёт 10 типов данных. Для каждого типа применяется собственный детектор с набором правил — в разных случаях это может быть проверка контрольной суммы, контекстные слова рядом или структурная валидация.
| Тип | Описание | Метод детекции |
|---|---|---|
email | Адреса электронной почты | Регулярное выражение |
phone | Российские номера телефонов | Структурные форматы (+7, 8 с разделителями) детектируются без контекста; «голые» номера — только рядом с контекстными словами («телефон», «позвони», и т.д.) |
passport | Паспорт РФ и загранпаспорт | Шаблон серии и номера с контекстными словами («паспорт», «серия», «документ») |
snils | СНИЛС | Проверка контрольной суммы по алгоритму ПФР |
inn | ИНН (10 или 12 цифр) | Проверка контрольной суммы |
ogrn | ОГРН (13 цифр) | Проверка контрольной суммы |
ogrnip | ОГРНИП (15 цифр) | Проверка контрольной суммы |
credit_card | Банковские карты | Проверка по алгоритму |
jwt | JWT-токены | Структурный анализ |
secret | Произвольные API-ключи и секреты | Эвристический анализ с учётом контекста |
Проверка контрольных сумм для ИНН, ОГРН, ОГРНИП, СНИЛС и банковских карт существенно снижает количество ложных срабатываний — случайные последовательности цифр не попадают в маскирование.
Вы можете включить все типы данных сразу или ограничиться подмножеством — настройка хранится на уровне аккаунта.
Помимо встроенных детекторов вы можете добавить собственные слова и фразы, которые должны маскироваться во всех запросах — например, названия внутренних проектов, имена клиентов, внутренние идентификаторы.
Каждая запись словаря — это пара «слово» + «замена»:
| Запись | Вхождение в тексте | Результат |
|---|---|---|
Газпром → Нефтегаз | Отчёт для Газпром за Q1 | Отчёт для Нефтегаз за Q1 |
Project Nimbus → [PROJECT] | обсудить Project Nimbus | обсудить [PROJECT] |
Правила:
- До 50 записей в словаре
- Слово — минимум 3 символа, до 200 символов
- Замена — обязательна, не пустая, до 200 символов
- Совпадение сравнивается без учёта регистра
- Совпадение происходит по границам слова: запись
userсработает наuser, но не наusername - Пары «слово + замена» должны быть уникальными
В режиме «с демаскированием» словарные замены так же восстанавливаются в ответе модели.
Маскирование работает только для текстовых чат-эндпоинтов:
- OpenAI Chat Completions —
/openai/v1/chat/completions - OpenAI Responses —
/openai/v1/responses - Anthropic Messages —
/anthropic/v1/messages - Google
generateContent/streamGenerateContent - OpenRouter Chat Completions —
/openrouter/v1/chat/completions
Маскирование не применяется к запросам генерации изображений, генерации видео, синтеза речи (TTS), распознавания речи (STT) и embeddings — семантика этих эндпоинтов делает замену текста некорректной или бессмысленной.
Внутри поддерживаемых эндпоинтов маскируются:
- Содержимое пользовательских и системных сообщений
- История диалога (предыдущие пользовательские сообщения)
- Результаты вызова инструментов (tool results / function results) — включая вложенные текстовые поля
Демаскирование в ответе модели работает не только на обычном текстовом содержимом, но и на аргументах вызовов инструментов — в том числе в стриминговых ответах. Если модель передала синтетическое значение в аргумент вызова инструмента, обработчик инструмента на стороне вашего приложения получит уже восстановленное оригинальное значение.
По умолчанию маскирование действует для всех API-ключей аккаунта. Вы можете ограничить его подмножеством ключей — это удобно, если вы хотите сначала включить маскирование только на тестовом или staging-ключе, а потом распространить на продакшн.
Когда маскирование действительно сработало на запросе, в ответ добавляются два заголовка:
X-ProxyAPI-Masked: true X-ProxyAPI-Masked-Types: email,phone
X-ProxyAPI-Masked-Types — это список типов данных (через запятую), которые были обнаружены и обработаны в этом запросе. Если маскирование настроено, но в запросе не было ничего подходящего, заголовки не добавляются.
Эти заголовки можно использовать на стороне вашего приложения, чтобы отличать запросы, прошедшие через маскирование, и при необходимости логировать факт срабатывания.
Маскирование полностью поддерживается для стриминговых ответов. SSE-события парсятся на лету, накапливается небольшой буфер текста, и оригинальные значения восстанавливаются в каждом чанке перед отправкой клиенту.
Есть небольшой побочный эффект: первое событие ответа задерживается на время, необходимое для накопления буфера — обычно это 50–200 мс. После этого стрим идёт в обычном темпе. Мы сознательно держим этот буфер минимально достаточным, чтобы исключить утечку фрагментов синтетических значений между токенами.
Если у вас одновременно включено логирование, в логи попадают только маскированные значения — оригинальные персональные данные не сохраняются в нашей инфраструктуре логирования ни в какой форме.
То есть если пользователь отправил в запросе свой паспорт, а у вас включены оба продукта:
- Провайдер модели получает синтетический паспорт
- В логах сохраняется синтетический паспорт
- Клиент вашего приложения получает реальный ответ с реальным паспортом (в режиме с демаскированием)
Это означает, что маскирование защищает данные не только от провайдера модели, но и от попадания в логи.
Если по какой-то причине сервис маскирования временно недоступен, ProxyAPI отклоняет запрос с HTTP 503 — запрос не отправляется провайдеру в обход маскирования. Это сознательное решение: безопасность по умолчанию важнее доступности. Такие ситуации редки и кратковременны.
- Маскирование работает только на текстовых чат-эндпоинтах, перечисленных выше.
- При стриминге с
n > 1(несколько вариантов ответа одновременно) у OpenAI / OpenRouter демаскируется только первый вариант (choices[0]). - Маскирование контекстно: для некоторых типов («голый» номер телефона, паспорт, произвольный секрет) требуется контекстное слово в пределах примерно 100 символов. Если контекста нет — значение может быть пропущено.
- Детекторы работают по шаблонам и словарю. Данные, описанные произвольной формулировкой (например, номер паспорта, записанный словами или с нестандартными разделителями), могут быть не распознаны.