# Qdrant self-hosted: API-ключ и проверка доступа без публикации сервера

Источник: https://modelium.tech/zhurnal/qdrant-api-key-self-hosted/

У самостоятельного Qdrant доступ к API по умолчанию не требует ключа. На закрытом стенде задайте отдельные admin и read-only ключи, оставьте порт только на 127.0.0.1 и проверьте три ответа: без ключа — отказ, с ключом чтения — список коллекций, с ним же на запись — отказ. Это не заменяет TLS и отдельную проверку прав на документы.

Если коллега получает доступ к вашему Qdrant, один ключ на все действия даёт ему и чтение, и изменение коллекций. На отдельном тестовом Linux-компьютере можно оставить полный ключ только администратору, а приложению выдать ключ чтения. **Здесь проверяется доступ к API — адресам для запросов программы к базе, — а не качество поиска или разграничение отдельных документов.** Qdrant — хранилище векторов для поиска; модель для превращения текста в векторы понадобится уже в другом сценарии, но не для проверки ключа. [s1](#src-s1) [s2](#src-s2)

**Проверено по документации 9 октября 2026 года**, ориентир — образ Qdrant `v1.19.2` и исходная конфигурация коммита `016542a`. Это инженерная инструкция для изолированного стенда, **не воспроизведённый тест Modelium**. Не используйте реальные документы или секреты в демонстрационной коллекции. [s3](#src-s3) [s4](#src-s4) [s6](#src-s6)

## Что нужно до настройки ключей?

Нужны Linux-хост с установленным Docker, локальный терминал, возможность сохранить два разных длинных случайных ключа в защищённом файле и свободные ресурсы под пустую тестовую коллекцию. Документация Qdrant не устанавливает универсальный минимум RAM/VRAM для этой проверки: здесь не загружается модель, а объём данных в будущем определяется вашей коллекцией. Скачивание образа и установка Docker требуют сети; запросы теста на `127.0.0.1` остаются на этой машине при отсутствии прокси и других сетевых компонентов. Это не доказывает офлайн-режим любого будущего приложения. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

**Не переносите команду быстрого старта с публикацией **`**6333:6333**`** на сервер в интернете.** Для примера ниже Docker публикует только HTTP-порт 6333 на адресе хоста `127.0.0.1`; порты 6334 и 6335 наружу не открываются. Qdrant внутри контейнера может слушать шире: проверяйте именно доступный адрес хоста и правила своей сети. **Docker Engine старше?** В версиях *до 28.0.0* Docker предупреждает о возможном доступе к опубликованному localhost-порту с соседнего узла той же сети; при особой прямой маршрутизации к контейнеру также нужен отдельный сетевой контроль. Проверьте версию Docker и недоступность порта извне, не доверяя одному флагу `-p`. Если к базе обращаются с другой машины, этот рецепт не подходит: потребуется частный сетевой контур и TLS — шифрование соединения, иначе ключ и данные передаются без защиты. [s1](#src-s1) [s3](#src-s3) [s5](#src-s5)

## Как включить два ключа на закрытом стенде?

- В отдельной папке на Linux создайте файл `qdrant-auth.env` с правами чтения **только для своего пользователя** (`chmod 600 qdrant-auth.env`). В нём должны быть ровно две строки вида `QDRANT__SERVICE__API_KEY=<АДМИН_КЛЮЧ>` и `QDRANT__SERVICE__READ_ONLY_API_KEY=<ДРУГОЙ_КЛЮЧ>`; вместо угловых скобок впишите два **разных случайных длинных значения** из вашего менеджера секретов. Не копируйте примерные ключи из документации, не публикуйте файл в Git и не оставляйте значение пустым. Это файл Docker `--env-file`, не URL и не заголовок запроса. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

- Из этой папки запустите новый **одноразовый** контейнер: `docker run -d --name qdrant-auth -p 127.0.0.1:6333:6333 -v qdrant_auth_storage:/qdrant/storage --env-file ./qdrant-auth.env qdrant/qdrant:v1.19.2`. Docker должен вернуть ID контейнера; если контейнер не запустился, смотрите `docker logs qdrant-auth` **не публикуя их вместе с секретами**. Это не команда для обновления уже существующей базы; у новой демонстрации отдельный именованный том. [s2](#src-s2) [s4](#src-s4) [s5](#src-s5) [s6](#src-s6)

- Для проверки с ключами заведите **локально**, отдельно от env-файла, два файла конфигурации `curl` с правами `chmod 600`: в `admin.curl` строка `header = "api-key: <АДМИН_КЛЮЧ>"`, в `reader.curl` — такая же строка с ключом чтения. Замените шаблоны реальными значениями только в личных файлах; в историю команд, URL, логи и общие скриншоты их не вставляйте. Для доступа с другой машины используйте TLS и доверенный сертификат, а не HTTP из этого локального примера. [s1](#src-s1) [s2](#src-s2)

## Как увидеть отказ без ключа и запрет записи?

На **том же Linux-хосте** отправьте `curl -i http://127.0.0.1:6333/collections` без заголовка. Ожидается **401 Unauthorized**. Если вернулся 200, **не подключайте рабочее приложение**: проверьте, что запрос попал именно в новый контейнер, обе переменные непустые, а процесс запущен с новым env-файлом. Не проверяйте авторизацию по одному только главному URL: используйте маршрут коллекций. Это ожидаемое поведение по официальному руководству, не результат запуска редакции. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

Теперь создайте только на **пустом демонстрационном стенде** коллекцию `auth_probe` полным ключом: `curl -i --config ./admin.curl -X PUT http://127.0.0.1:6333/collections/auth_probe -H 'Content-Type: application/json' -d '{"vectors":{"size":3,"distance":"Cosine"}}'`. Проверьте успешный ответ, затем `curl -i --config ./reader.curl http://127.0.0.1:6333/collections/auth_probe`: ключ чтения должен получить сведения о коллекции. Трёхмерный вектор здесь лишь синтетическая настройка пустой коллекции; это **не** размерность готовой embedding-модели и не тест поиска. [s1](#src-s1) [s2](#src-s2)

Отправьте с ключом чтения запрос **только к **`**auth_probe**`: `curl -i --config ./reader.curl -X POST http://127.0.0.1:6333/collections/auth_probe/points/delete -H 'Content-Type: application/json' -d '{"points":[999999]}'`. В свежей пустой коллекции такой точки нет; ожидается **403 Forbidden** до изменения данных. Если операция вернула успех, прекратите тест и пересмотрите права: ключ чтения не должен удалять точки. На реальной коллекции удаление не испытывайте. После проверки можно выполнить `docker stop qdrant-auth` и `docker rm qdrant-auth`; отдельный том `qdrant_auth_storage` и локальные файлы ключей удаляйте только после проверки, что они больше не нужны. [s1](#src-s1) [s2](#src-s2)

## Что этот тест не защищает?

Оба обычных ключа действуют **на все коллекции**: read-only запрещает запись, но не скрывает чужие данные от чтения. Для прав на отдельные коллекции у Qdrant есть токены с ограниченной областью доступа (JWT) при отдельной настройке `jwt_rbac`; для документов внутри одной коллекции нужна авторизация вашего приложения. Фильтр `tenant_id` сам по себе не право доступа, если пользователь может убрать или изменить его в запросе. Откройте [проверку доступа к корпоративным документам](/zhurnal/korporativnyy-poisk-prava-dostupa/) после теста 401/403; для исходного локального поиска есть [гайд Qdrant](/zhurnal/qdrant-lokalno/), а [метаданные и фильтры](/zhurnal/qdrant-filtry-metadannyh/) разобраны отдельно. [s1](#src-s1) [s2](#src-s2)

При переходе от одноразового стенда к работе не выдавайте admin-ключ клиентам, не открывайте 6333/6334/6335 в интернет, включите TLS и журналирование в зависимости от модели угроз. Если контейнер запущен, но получены неожиданные 401/403, сначала сверьте заголовок `api-key`, адрес, ключи и конфигурацию запуска, не раскрывая их в сообщении об ошибке. Ни 401/403, ни наличие ключа **не доказывают** сетевую изоляцию, защищённость документов или фактическую работу локальной модели. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

## Источники

1. [Qdrant: Security & Access Control](https://qdrant.tech/documentation/security.md) — получено 2026-10-09
2. [Qdrant: Secure a Self-Hosted Qdrant Instance](https://qdrant.tech/documentation/tutorials-operations/secure-qdrant.md) — получено 2026-10-09
3. [Qdrant v1.19.2: исходная конфигурация сервиса](https://raw.githubusercontent.com/qdrant/qdrant/016542aa5deb6c66380bb137badf73d54f742bde/config/config.yaml) — получено 2026-10-09
4. [Qdrant: официальный образ Docker v1.19.2](https://hub.docker.com/r/qdrant/qdrant/tags?name=v1.19.2) — получено 2026-10-09
5. [Docker: publishing and binding container ports](https://docs.docker.com/engine/network/port-publishing/) — получено 2026-10-09
6. [Qdrant: официальный релиз v1.19.2](https://github.com/qdrant/qdrant/releases/tag/v1.19.2) — получено 2026-10-09
