Qdrant - Vector Database
Security и Auth: защита Qdrant
В 2023 году ElasticSearch без аутентификации был причиной 40% утечек данных в cloud-based системах. Qdrant по умолчанию тоже открыт. Три строки в config.yaml отделяют вас от подобной утечки.
- **SaaS multi-tenant:** backend генерирует short-lived JWT для каждого tenant → Qdrant проверяет JWT и разрешает доступ только к нужной коллекции
- **Compliance (GDPR/SOC2):** audit logging фиксирует кто, когда и какие данные читал — требование регуляторов
- **Zero Trust Kubernetes:** TLS + mTLS между всеми сервисами, API key в env variables — минимальный production hardening
Предварительные знания
Static API Keys: базовая аутентификация
По умолчанию Qdrant запускается **без аутентификации** - любой запрос к порту 6333 принимается. В production это неприемлемо. Простейший способ защиты - **Static API Key**: секрет, который клиент передаёт в заголовке каждого запроса. Qdrant поддерживает два типа static keys: - **api_key** - полный доступ (чтение + запись) - **read_only_api_key** - только чтение (поиск, scroll, getPoints)
**Когда хватает static key:** один сервис = один ключ. Подходит для backend-to-Qdrant коммуникации, CI/CD скриптов, admin инструментов. Не подходит когда нужен **разный доступ для разных клиентов** (например, каждый пользователь SaaS должен видеть только свои данные) - для этого нужен JWT.
Ваш frontend напрямую обращается к Qdrant для поиска (React → Qdrant). Какую аутентификацию использовать?
JWT: collection-level access control
**JWT authentication** в Qdrant (v1.7+) позволяет ограничить доступ к конкретным коллекциям. Qdrant проверяет JWT используя `api_key` как HMAC-SHA256 секрет. Это позволяет реализовать **multi-tenant access control**: каждый tenant получает JWT с доступом только к своим коллекциям. JWT payload для Qdrant: - `exp` - время истечения токена (Unix timestamp) - `value_exists` - ограничение по коллекциям (array условий)
**JWT vs Static key:** static key - одно значение на весь инстанс. JWT - динамически генерируемые токены с expiry и scope. JWT идеален для SaaS: каждый tenant получает токен с доступом только к своей коллекции. Токен истекает через N часов - минимизирует ущерб при компрометации. **Важно:** Qdrant использует `api_key` из config.yaml как HMAC secret для проверки JWT - нужно хранить api_key как основной секрет.
SaaS приложение: 1000 клиентов, у каждого своя Qdrant коллекция. Клиент делает поиск через браузер. Как организовать доступ?
TLS и Audit Logging: production-hardened конфигурация
**TLS (HTTPS)** шифрует трафик между клиентом и Qdrant. Без TLS, API key и JWT токены передаются в открытом виде - перехват даёт полный доступ к системе. Особенно важно при деплое в облаке где трафик идёт через публичные сети. **Audit logging** (v1.17+) - логирование всех операций чтения и записи. Полезно для: - Compliance (GDPR, SOC2 требуют audit trails) - Расследование инцидентов безопасности - Дебаггинг production проблем
**TLS в production - обязательно.** API key в HTTP запросе виден в логах nginx/load balancer, перехватывается на сетевом уровне, виден в tcpdump. Даже во внутренней сети облака - TLS обязателен. Исключение: localhost development без внешнего трафика. Минимальный production checklist: TLS + api_key + read_only_api_key + audit_log.
«Qdrant внутри VPC/Kubernetes - незачем шифровать, там безопасно»
Сетевой уровень защиты (VPC, NetworkPolicy) не заменяет шифрование. Компрометация одного сервиса = возможность перехватить незашифрованный трафик к Qdrant.
Реальные атаки: контейнер с уязвимостью получает доступ к внутренней сети → tcpdump перехватывает api_key в HTTP заголовках → полный доступ к Qdrant. С TLS: перехваченный трафик зашифрован, api_key недоступен. Defence in depth: VPC + NetworkPolicy + TLS = три независимых барьера.
Qdrant запущен в Kubernetes кластере. Поды backend общаются с Qdrant внутри кластера через ClusterIP сервис. Нужен ли TLS?
Итоги
- **Static API key:** `service.api_key` в config.yaml или env `QDRANT__SERVICE__API_KEY`. Передаётся в заголовке `api-key`. `read_only_api_key` — только чтение.
- **JWT auth:** api_key используется как HMAC-SHA256 secret. Payload: `value_exists` ограничивает доступ к коллекции, `exp` — время истечения. Идеально для multi-tenant SaaS.
- **TLS:** `tls.cert` и `tls.key` в config.yaml. HTTPS на порту 6333, gRPC+TLS на 6334. Обязательно в production.
- **Audit logging** (v1.17+): `service.enable_audit_log: true`. JSON в stdout: action, collection, client_ip, auth_type, result, latency_ms.
- **Production checklist:** TLS + api_key + read_only_api_key + audit_log + NetworkPolicy + хранить ключи в secrets manager
Что дальше
Данные защищены. Следующий шаг - производительность: gRPC протокол для высокопроизводительного взаимодействия с Qdrant.
- gRPC протокол — gRPC поддерживает TLS из коробки - security + performance в одном
- Мультитенантность — JWT auth - ключевая часть collection-per-tenant архитектуры
- Cloud vs Self-hosted — В Qdrant Cloud security управляется платформой - другая модель аутентификации
Вопросы для размышления
- JWT токен Qdrant подписан api_key. Что произойдёт если api_key изменится? Как управлять rotation ключей без даунтайма?
- Как ограничить доступ по IP адресу (только backend серверы могут обращаться к Qdrant)? На каком уровне это делается?
- Audit log пишется в stdout. Как организовать retention и alerting для аномалий (например, необычно большой scroll от неизвестного IP)?