Контроль утечки данных в LLM: прокси-слой с маскированием и фильтрацией

· безопасность прокси утечка-данных ai

Большие языковые модели живут «в облаке», поэтому каждый запрос с паспортными данными, номерами карт или телефонами потенциально уходит во внешний сервис и остаётся в его логах. Прокси-слой перед LLM решает эту проблему: он перехватывает исходящие запросы, находит чувствительные паттерны и маскирует их до отправки. Ниже — как собрать такой фильтр и подключить его к API-шлюзу TokenMaster.

Что понадобится

  • Python 3.8+ — стандартной библиотеки достаточно, тяжёлые зависимости не нужны.
  • API-ключ TokenMaster вида sk-… — создаётся в разделе «Ключи» после регистрации на tokenmaster.ru.
  • Список regex-паттернов для данных, которые нельзя отдавать наружу: паспорта, карты, телефоны, email.

Собираем фильтр на Python

Начнём с функции маскирования. Она ищет в тексте знакомые форматы и заменяет их на безопасные заглушки, сохраняя полезную часть запроса:

import re

# Паттерны: паспорт РФ, банковская карта, телефон, email
PATTERNS = {
    "passport": r"\b\d{4}\s?\d{6}\b",
    "card":     r"\b\d{4}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b",
    "phone":    r"\+?7[ (]?\d{3}[ )]?\d{3}[- ]?\d{2}[- ]?\d{2}",
    "email":    r"\b[\w.+-]+@[\w-]+\.[\w.]+\b",
}

def mask_text(text: str) -> str:
    for kind, pattern in PATTERNS.items():
        text = re.sub(
            pattern,
            lambda m: f"<{kind.upper()}:{len(m.group(0))} символов>",
            text,
        )
    return text

Теперь превратим это в настоящий прокси: он принимает локальные запросы, маскирует содержимое сообщений, пишет в лог только факт обращения и размер (а не сам текст) и пересылает всё в TokenMaster.

import json
import http.server
import urllib.request

TOKENMASTER = "https://tokenmaster.ru/v1"
API_KEY = "sk-ваш-ключ"

class FilterProxy(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get("Content-Length", 0))
        body = json.loads(self.rfile.read(length))

        # Маскируем текст сообщений до отправки наружу
        for msg in body.get("messages", []):
            if isinstance(msg.get("content"), str):
                msg["content"] = mask_text(msg["content"])

        # Логируем только факт и размер, без содержимого
        print(f"[proxy] {self.path} — {length} байт после фильтра")

        req = urllib.request.Request(
            TOKENMASTER + self.path,
            data=json.dumps(body).encode(),
            headers={
                "Authorization": f"Bearer {API_KEY}",
                "Content-Type": "application/json",
            },
            method="POST",
        )
        with urllib.request.urlopen(req) as resp:
            data = resp.read()

        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(data)

http.server.HTTPServer(("127.0.0.1", 8787), FilterProxy).serve_forever()

Запустите скрипт командой python proxy.py — прокси поднимется на http://127.0.0.1:8787. Все приложения внутри сети теперь ходят не напрямую в LLM, а через этот слой.

Если у вас уже стоит nginx, ту же логику можно сделать без Python — модулем Lua перехватывать тело запроса и подменять совпадения до proxy_pass на https://tokenmaster.ru/v1. Принцип одинаков: фильтр стоит перед отправкой наружу и не пропускает сырые данные.

Подключение TokenMaster

TokenMaster — это AI-шлюз с OpenAI-совместимым API, поэтому прокси не нужно адаптировать под конкретную модель:

  • Base URL: https://tokenmaster.ru/v1
  • API Key: ваш ключ вида sk-…

Прокси проксирует запросы «как есть», меняя только содержимое сообщений. Один ключ и один баланс дают доступ к нескольким семействам моделей — DeepSeek (deepseek-flash, deepseek-v4-pro), GLM / Zhipu (glm-4.5, glm-5) и Qwen. Оплата принимается из России, без привязки к зарубежной карте. Подробнее о моделях — в документации tokenmaster.ru/docs.

Проверка работы

Отправьте через прокси запрос с «запрещённым» содержимым и убедитесь, что оно ушло наружу уже в маскированном виде:

import json, urllib.request

body = {
    "model": "deepseek-flash",
    "messages": [
        {"role": "user", "content": "Клиент: Иванов, паспорт 4512 345678, карта 4276 1234 5678 9012, тел. +7 900 123-45-67"}
    ],
}
req = urllib.request.Request(
    "http://127.0.0.1:8787/chat/completions",
    data=json.dumps(body).encode(),
    headers={"Content-Type": "application/json"},
)
print(urllib.request.urlopen(req).read().decode())

В логе прокси появится строка о размере запроса, а модель получит уже <PASSPORT:11 символов> и <CARD:19 символов> вместо реальных данных. Если возникла ошибка:

  • 401 / invalid api key — ключ TokenMaster неверный или скопирован не целиком (он должен начинаться с sk-).
  • connection error — проверьте, что прокси пересылает запросы ровно на https://tokenmaster.ru/v1, без лишнего /chat/completions в Base URL.
  • insufficient quota — на балансе TokenMaster недостаточно средств, пополните его в разделе «Кошелёк».

Частые вопросы

Не портит ли маскирование качество ответа модели? Для большинства задач нет: модель всё равно видит тип данных и их длину, а не конкретные значения. Если для ответа реально нужны сами данные, лучше обработать их локально, а модели отдать только обезличенный результат.

Можно ли фильтровать не только текст, а целые запросы? Да. По тем же паттернам можно блокировать запрос целиком: если счётчик совпадений превысил порог, возвращать ошибку клиенту, не отправляя ничего наружу. Это удобно, когда нужно жёсткое правило, а не мягкое маскирование.

Что делать, если данные уже могли утечь раньше? Прокси защищает будущие запросы, но не отменяет прошлые. Ротация ключей API, пересмотр того, что вы отправляете моделям, и включение фильтра на уровне всей команды снижают риск повторной утечки.

Итог

Прокси-слой перед LLM — это простой и надёжный способ контролировать, какие данные уходят во внешние модели: он маскирует паспорта, карты и телефоны по regex, пишет аккуратные логи без чувствительного содержимого и не требует менять привычный код. Подключите его к шлюзу TokenMaster через Base URL https://tokenmaster.ru/v1 и ключ sk-… — и ваши запросы станут заметно безопаснее без потери удобства.

Подключите модели через TokenMaster

Один ключ sk-… и base URL https://tokenmaster.ru/v1 — доступ к DeepSeek, GLM, Qwen и другим моделям. Зарегистрироваться →