Безопасность LLM-интеграции

Руководство по защите данных при работе с поставщиками LLM


Содержание

Обзор

Модуль SecureLLMProvider обеспечивает комплексную защиту при работе с внешними поставщиками LLM (GigaChat, Yandex AI Studio, OpenAI и др.). Модуль реализует принцип “defence in depth” — многоуровневую защиту данных.

Гарантии безопасности

Гарантия Реализация
Код не передаётся Только NL-запросы отправляются в LLM
Pre-request DLP Сканирование ContentScanner до отправки
Post-response DLP Маскирование в ответах
Полный аудит Логирование каждого запроса
SIEM-интеграция События в реальном времени
Секреты в Vault API-ключи в HashiCorp Vault

Архитектура

Конвейер обработки запроса

+---------------------------------------------------------------------------+
|                         SecureLLMProvider                                   |
|                                                                            |
|  +-------------------------------------------------------------------+    |
|  |                     1. PRE-REQUEST PHASE                           |    |
|  |                                                                    |    |
|  |  User Query --> [ContentScanner] --+--> BLOCK --> DLPBlockedException  |
|  |                                    |                               |    |
|  |                                    +--> MASK --> Masked Query      |    |
|  |                                    |                               |    |
|  |                                    +--> WARN --> Original + Event  |    |
|  |                                    |                               |    |
|  |                                    +--> PASS --> Original Query    |    |
|  |                                                    |               |    |
|  |                                    +---------------+               |    |
|  |                                    v                               |    |
|  |                             [SIEM Event]                           |    |
|  +-------------------------------------------------------------------+    |
|                                       |                                    |
|                                       v                                    |
|  +-------------------------------------------------------------------+    |
|  |                    2. LLM PROVIDER CALL                            |    |
|  |                                                                    |    |
|  |  [VaultClient] --> API Key --> [GigaChat/Yandex AI/OpenAI] --> Response |
|  |                                                                    |    |
|  |  * API-ключ из Vault                                               |    |
|  |  * TLS-соединение                                                  |    |
|  |  * Request ID tracking                                             |    |
|  +-------------------------------------------------------------------+    |
|                                       |                                    |
|                                       v                                    |
|  +-------------------------------------------------------------------+    |
|  |                   3. POST-RESPONSE PHASE                           |    |
|  |                                                                    |    |
|  |  Response --> [ContentScanner] --> Mask Sensitive Data --> User     |    |
|  |                     |                                              |    |
|  |                     v                                              |    |
|  |              [SIEM Event]                                          |    |
|  +-------------------------------------------------------------------+    |
|                                       |                                    |
|                                       v                                    |
|  +-------------------------------------------------------------------+    |
|  |                     4. AUDIT LOGGING                               |    |
|  |                                                                    |    |
|  |  * Request ID                  * Token usage                       |    |
|  |  * User ID                     * Latency                          |    |
|  |  * Session ID                  * DLP matches                       |    |
|  |  * IP address                  * Error details                     |    |
|  |                                                                    |    |
|  |  --> [PostgreSQL] + [SIEM]                                         |    |
|  +-------------------------------------------------------------------+    |
+---------------------------------------------------------------------------+

Принципы защиты данных

1. Исходный код не передаётся

+------------------------------------------------------------------+
|                      ПЕРИМЕТР ОРГАНИЗАЦИИ                          |
|                                                                    |
|   [Source Code] --> [CPG Analysis] --> [DuckDB]                    |
|                                           |                        |
|                                           v                        |
|   [User] --> "Find buffer overflow in function X"                  |
|                           |                                        |
|                           v                                        |
|                   [RAG Query Engine]                               |
|                           |                                        |
|                           v                                        |
|               NL Query (no code snippets)                          |
|                           |                                        |
+---------------------------+----------------------------------------+
                            |
                            v
                 [GigaChat/Yandex API]
                            |
                            v
               NL Response (explanation)

Что передаётся LLM: - Текстовые запросы пользователей - Метаданные (имена функций, файлов) - Структурированные данные из CPG

Что НЕ передаётся: - Исходный код - Содержимое файлов - Строки подключения - Секреты и учётные данные


Справочник API

SecureLLMProvider

from src.security.llm import SecureLLMProvider
from src.security.config import get_security_config
from src.llm.gigachat_provider import GigaChatProvider

# Создание защищённого поставщика
base_provider = GigaChatProvider(config)
secure_provider = SecureLLMProvider(
    wrapped_provider=base_provider,
    config=get_security_config()
)

# Использование (с контекстом безопасности)
response = secure_provider.generate(
    system_prompt="You are a security analyst.",
    user_prompt="Analyze this function for vulnerabilities.",
    _user_id="analyst@company.com",
    _session_id="sess-12345",
    _ip_address="10.0.0.50"
)

Методы

Метод Описание
generate(system_prompt, user_prompt, **kwargs) Генерация с полной защитой
generate_simple(prompt, **kwargs) Упрощённый вызов
generate_stream(system_prompt, user_prompt, **kwargs) Потоковая генерация
is_available() Проверка доступности поставщика

Контекстные параметры

Параметр Описание
_user_id ID пользователя для аудита
_session_id ID сессии
_ip_address IP-адрес клиента

ContentScanner

Класс ContentScanner (src/security/dlp/scanner.py) выполняет DLP-сканирование на этапах pre-request и post-response. Используется внутри SecureLLMProvider, но доступен и напрямую:

from src.security.dlp import ContentScanner

scanner = ContentScanner(config.dlp)
result = scanner.scan_request(text)   # Pre-request сканирование
result = scanner.scan_response(text)  # Post-response сканирование

Конфигурация

Полная конфигурация (config.yaml)

security:
  enabled: true

  # Логирование LLM-взаимодействий
  llm_logging:
    enabled: true
    log_prompts: true           # Логировать промпты
    redact_prompts: true        # Редактировать чувствительные данные
    max_prompt_length: 2000     # Макс. длина в логе
    log_responses: true         # Логировать ответы
    max_response_length: 5000   # Макс. длина ответа в логе
    log_token_usage: true       # Логировать использование токенов
    log_latency: true           # Логировать задержку
    log_to_database: true       # Сохранять в PostgreSQL
    log_to_siem: true           # Отправлять в SIEM

  # DLP-конфигурация
  dlp:
    enabled: true
    pre_request:
      enabled: true
      default_action: WARN
    post_response:
      enabled: true
      default_action: MASK

  # SIEM-интеграция
  siem:
    enabled: true
    syslog:
      enabled: true
      host: "siem.company.com"
      port: 514

  # HashiCorp Vault
  vault:
    enabled: true
    url: "https://vault.company.com:8200"
    auth_method: "approle"
    llm_secrets_path: "codegraph/llm"

Обработка ошибок

DLPBlockedException

from src.security.dlp import DLPBlockedException

try:
    response = secure_provider.generate(
        system_prompt="...",
        user_prompt=user_input
    )
except DLPBlockedException as e:
    # Запрос заблокирован DLP
    logger.warning(f"DLP blocked: {e.message}")

    # Информация о нарушениях
    for match in e.matches:
        print(f"Category: {match.category}")
        print(f"Pattern: {match.pattern_name}")
        print(f"Severity: {match.severity}")

    # Вернуть ошибку клиенту
    return {
        "error": "dlp_blocked",
        "message": "Request contains sensitive data",
        "categories": e.to_dict()["categories"]
    }

Структура ошибки

{
  "error": "dlp_blocked",
  "message": "Request blocked by DLP policy. Detected 2 violation(s) in categories: credentials, pii. Please remove sensitive data before retrying.",
  "categories": ["credentials", "pii"],
  "violation_count": 2
}

Управление секретами

Интеграция с HashiCorp Vault

from src.security.vault import VaultClient
from src.security.config import get_security_config

config = get_security_config()
vault = VaultClient(config.vault)

# Получение учётных данных LLM
credentials = vault.get_llm_credentials()

# Результат (из env-переменных):
# {
#   "gigachat_credentials": "...",
#   "gigachat_api_key": "...",
#   "openai_api_key": "sk-...",
#   "anthropic_api_key": "sk-ant-...",
#   "azure_openai_api_key": "...",
#   "azure_openai_endpoint": "https://..."
# }

Примечание: get_llm_credentials() получает учётные данные для GigaChat, OpenAI, Anthropic и Azure OpenAI. Учётные данные Yandex (YANDEX_API_KEY, YANDEX_FOLDER_ID) управляются отдельно через config.yaml и не хранятся в Vault.

Резервное переключение на переменные окружения

При недоступности Vault используются переменные окружения:

Переменная Поставщик
GIGACHAT_CREDENTIALS GigaChat
GIGACHAT_API_KEY GigaChat (альтернатива)
YANDEX_API_KEY Yandex AI Studio
YANDEX_FOLDER_ID Yandex Cloud Folder
OPENAI_API_KEY OpenAI
ANTHROPIC_API_KEY Anthropic
AZURE_OPENAI_API_KEY Azure OpenAI
AZURE_OPENAI_ENDPOINT Azure OpenAI Endpoint

Аудит и логирование

Структура лога запроса

{
  "timestamp": "2026-02-26T10:30:00.000Z",
  "request_id": "req-12345",
  "event": "llm_request",
  "provider": "GigaChatProvider",
  "model": "GigaChat-2-Pro",
  "user_id": "analyst@company.com",
  "session_id": "sess-67890",
  "ip_address": "10.0.0.50",
  "latency_ms": 1250.5,
  "tokens": {
    "prompt_tokens": 150,
    "completion_tokens": 450,
    "total_tokens": 600
  },
  "dlp": {
    "pre_request_matches": 0,
    "post_response_matches": 1,
    "action": "MASK"
  }
}

SIEM-события

Событие Когда отправляется
LLM_REQUEST При отправке запроса поставщику LLM
LLM_RESPONSE При получении ответа от поставщика LLM
LLM_ERROR При ошибке поставщика LLM
DLP_BLOCK При блокировке запроса DLP (action=BLOCK)
DLP_MASK При маскировании данных DLP (action=MASK)
DLP_WARN При обнаружении совпадения с логированием предупреждения (action=WARN)
DLP_LOG При логировании совпадения для аудита без действия (action=LOG)

Потоковая генерация

Особенности потокового режима

# Потоковая генерация с защитой
for chunk in secure_provider.generate_stream(
    system_prompt="You are a security analyst.",
    user_prompt="Explain this vulnerability.",
    _user_id="analyst@company.com"
):
    # Chunk уже прошёл pre-request DLP
    print(chunk, end="", flush=True)

# Post-response DLP выполняется после завершения потока
# Если обнаружены чувствительные данные — событие в SIEM

Ограничения потокового режима: - Pre-request DLP работает полностью - Post-response DLP логирует совпадения, но не может модифицировать уже отправленные chunks - Рекомендуется для интерактивных сценариев с низким риском


Метрики и мониторинг

Prometheus-метрики

Все метрики, связанные с LLM, используют префикс rag_:

# Количество запросов
rate(rag_total_requests[5m])

# Средняя задержка LLM (P95)
histogram_quantile(0.95, rate(rag_llm_latency_seconds_bucket[5m]))

# Использование токенов по моделям
sum(rate(rag_llm_tokens_total[1h])) by (model, token_type)

# Ошибки LLM по модели и типу
rate(rag_llm_errors_total[5m])
Метрика Тип Метки Описание
rag_total_requests Counter Общее количество обработанных запросов
rag_active_requests Gauge Запросы в обработке
rag_llm_latency_seconds Histogram model, operation Задержка вызовов LLM API
rag_llm_tokens_total Counter model, token_type Использование токенов
rag_llm_errors_total Counter model, error_type Ошибки LLM API

Примечание: Отдельной метрики для DLP-блокировок нет. DLP-события отслеживаются через SIEM (DLP_BLOCK, DLP_WARN и т.д.).

Grafana Dashboard

{
  "panels": [
    {
      "title": "LLM Requests per Minute",
      "query": "rate(rag_total_requests[1m])"
    },
    {
      "title": "P95 Latency",
      "query": "histogram_quantile(0.95, rate(rag_llm_latency_seconds_bucket[5m]))"
    },
    {
      "title": "Token Usage by Model",
      "query": "sum(rate(rag_llm_tokens_total[1h])) by (model)"
    },
    {
      "title": "LLM Errors",
      "query": "rate(rag_llm_errors_total[5m])"
    }
  ]
}

Лучшие практики

Для разработчиков

  1. Всегда передавайте контекст_user_id, _session_id, _ip_address
  2. Обрабатывайте DLPBlockedException — информируйте пользователя
  3. Используйте потоковый режим осторожно — понимайте ограничения post-DLP
  4. Не логируйте ответы целиком — используйте max_response_length

Для операторов

  1. Отслеживайте DLP-события — мониторьте DLP_BLOCK/DLP_WARN в SIEM
  2. Настройте оповещения на LLM_ERROR — ошибки поставщика требуют внимания
  3. Ротируйте API-ключи — используйте Vault с автоматической ротацией
  4. Аудит токенов — отслеживайте аномальное потребление

Для обеспечения соответствия

  1. Документируйте потоки данных — какие данные и куда передаются
  2. Храните логи — минимум 1 год для обеспечения соответствия
  3. Регулярный аудит — проверяйте эффективность DLP
  4. Реагирование на инциденты — план реагирования на DLP_BLOCK

Примечание: Структурированные шаблоны промптов управляются через глобальный реестр промптов (config/prompts/), что обеспечивает централизованный аудит и версионирование всех LLM-промптов, используемых платформой.


Связанные документы


Версия: 1.2 | Март 2026