Плагины
Роутер умеет обрабатывать запрос дополнительными плагинами. Плагин включается на конкретный запрос через поле plugins в теле. Сейчас доступен DLP (data loss prevention).
DLP сканирует ввод пользователя на чувствительные данные (секреты и PII) и реагирует по выбранному режиму.
{ "model": "anthropic/claude-sonnet-4.6", "plugins": { "dlp": { "mode": "mask" } }}Поле plugins необязательное, но его отсутствие не отменяет проверку: у API-ключа бывает своя политика DLP, заданная администратором группы. См. Политика API-ключа.
mode |
Поведение |
|---|---|
alert |
Найденное возвращается в ответе (plugins.dlp), запрос проходит как есть |
mask |
Совпадения заменяются токенами перед отправкой в модель, в ответе восстанавливаются обратно |
block |
Запрос отклоняется с 403 и кодом dlp_violation, в extra.dlp перечислены находки |
Типы данных (entity_types)
Заголовок раздела «Типы данных (entity_types)»Секреты и креды: ACCESS_TOKEN, API_KEY, BEARER_TOKEN, CERTIFICATE, JWT, PASSWORD, PRIVATE_KEY, PUBLIC_KEY, UNKNOWN_SECRET.
PII и идентификаторы: BANK_ACCOUNT, CREDIT_CARD, DOB, EMAIL, ID_NUMBER, IP_ADDRESS, MAC_ADDRESS, MEDICAL_ID, PHONE_NUMBER, POSTAL_CODE, SSN, SWIFT_BIC, TAX_ID, VEHICLE_VIN, а также российские KPP, OGRN, OGRNIP, OMS. Детекторы работают на EN и RU.
Поле необязательное. Без него проверяются все типы кроме UNKNOWN_SECRET: его находит анализ энтропии, а не шаблон, поэтому он даёт ложные срабатывания на длинных случайных строках и включается только явно. Если у ключа есть политика, без этого поля действуют её категории, а не полный список.
Политика API-ключа
Заголовок раздела «Политика API-ключа»У API-ключа может быть политика DLP, заданная администратором группы. Она применяется как пол строгости: независимо от того, присылаете вы plugins.dlp или нет, запрос проверяется минимум по ней. У клиентов, написанных под стандарты OpenAI и Anthropic, поля для DLP-конфига нет вовсе, и на них политика тоже действует.
Ваш конфиг продолжает действовать, но только в сторону ужесточения:
| Поле | Что с ним делает объединение |
|---|---|
mode |
Действует на правила, которые объявили вы. Если то же правило есть и в политике, побеждает более строгий режим: alert слабее mask, mask слабее block |
entity_types |
Объединение категорий. Не прислали поле, действуют категории политики |
stop_words |
Объединение списков запрещённых литералов |
regexes |
Объединение списков собственных шаблонов |
allowlist |
Действует только на находки по вашим правилам. Находку по правилу политики исключение не отменяет |
report_scope |
Остаётся вашим, он выбирает только состав возвращаемых находок, а не решение о блокировке |
Ещё два поля под политикой обнуляются: injected_context_names и acknowledged. Первое выводит помеченное сообщение из проверки, и под политикой это был бы способ от неё уклониться; второе и без политики ни на что не влияет.
Реакцию на находку задаёт тот, кто объявил сработавшее правило. Если вы перечислили entity_types, ваш режим действует на эти категории, на ваши стоп-слова и на ваши шаблоны, а по остальным категориям политики отвечает режим администратора. Если entity_types вы не прислали, ваш режим действует на все категории политики. Где правило объявлено с обеих сторон, побеждает более строгий режим.
Исключения подчиняются той же принадлежности: ваше исключение снимает находку по вашему правилу и не дотягивается до правила политики. Внутри вашего конфига запрет сильнее исключения: значение, объявленное и стоп-словом, и исключением, остаётся запрещённым.
Содержимое политики администратора вам не видно, и отдельной ошибки о том, что ваша настройка ослаблена, не приходит: применяется более строгая. Изменение настроек администратора доходит до проверки примерно за минуту.
Когда политика недоступна
Заголовок раздела «Когда политика недоступна»Если политику ключа не удалось получить, запрос отклоняется с 503 и кодом dlp_policy_unavailable, а в заголовке Retry-After приходит интервал для повтора. Проверка не выключается сама: запрос без известной политики не уходит в модель.
Этот код отличается от dlp_unavailable, который тоже приходит с 503. Разница в реакции: dlp_policy_unavailable лечится повтором, а dlp_unavailable говорит, что DLP не включён, и повтор вернёт тот же ответ.
Ошибка блокировки
Заголовок раздела «Ошибка блокировки»{ "error": { "code": "dlp_violation", "message": "Request blocked: sensitive data detected", "extra": { "dlp": [ { "category": "pii", "entity_type": "EMAIL", "message_index": 0, "location": "messages[0].content", "start": 12, "end": 28, "confidence": 0.98 } ], "findings_count": 1, "block_scope": "in_report_scope" } }}На /v1/messages тело в формате Anthropic: тип ошибки permission_error, машинный код рядом с ним в поле code, находки в details.
{ "type": "error", "error": { "type": "permission_error", "code": "dlp_violation", "message": "Request blocked: sensitive data detected", "details": { "dlp": [ { "category": "pii", "entity_type": "EMAIL", "message_index": 0, "location": "messages[0].content", "start": 12, "end": 28, "confidence": 0.98 } ], "findings_count": 1, "block_scope": "in_report_scope" } }}Находка описывает место и класс совпадения: категория (secret, pii, custom), тип сущности, позиция в тексте. Самих значений в ней нет, и восстановить их по ответу нельзя. У находки по стоп-слову тип сущности STOP_WORD, по вашему шаблону CUSTOM_REGEX; категория у обоих custom.
Поле block_scope говорит, где лежит причина блокировки: in_report_scope, если она среди перечисленных находок, и outside_report_scope, если она в той части запроса, которую мы не возвращаем.
Блокировка всегда приходит обычным HTTP-ответом, в том числе при stream: true: решение принимается до открытия потока, поэтому событием внутри стрима она не бывает.