Skip to main content
Qdrant provides multiple security layers including API key authentication, TLS/SSL encryption, JWT-based RBAC, and audit logging to protect your vector database.

API Key Authentication

Protect your Qdrant instance with API keys for authentication.

Standard API Key

Set a full-access API key in your configuration:
config/config.yaml
service:
  api_key: your_secret_api_key_here
Or use environment variables:
QDRANT__SERVICE__API_KEY=your_secret_api_key_here
With Docker:
docker run -p 6333:6333 \
    -e QDRANT__SERVICE__API_KEY=your_secret_api_key_here \
    qdrant/qdrant:latest

Using the API Key

Include the API key in the api-key header:
curl -X GET http://localhost:6333/collections \
    -H 'api-key: your_secret_api_key_here'
from qdrant_client import QdrantClient

client = QdrantClient(
    url="http://localhost:6333",
    api_key="your_secret_api_key_here"
)

collections = client.get_collections()
Never send API keys over unencrypted connections. Always enable TLS when using API key authentication in production.

Read-Only API Key

Provide read-only access with a separate API key:
config/config.yaml
service:
  api_key: your_secret_api_key_here
  read_only_api_key: your_read_only_key_here
With environment variables:
QDRANT__SERVICE__API_KEY=your_secret_api_key_here
QDRANT__SERVICE__READ_ONLY_API_KEY=your_read_only_key_here

Read-Only Permissions

The read-only API key allows:
  • ✅ Search and retrieval operations
  • ✅ Collection listing and info
  • ✅ Point retrieval
  • ✅ Scroll and batch retrieval
  • ❌ Creating or deleting collections
  • ❌ Inserting, updating, or deleting points
  • ❌ Creating snapshots

Using Read-Only Key

curl -X POST http://localhost:6333/collections/my_collection/points/search \
    -H 'api-key: your_read_only_key_here' \
    -H 'Content-Type: application/json' \
    -d '{
        "vector": [0.1, 0.2, 0.3, 0.4],
        "limit": 10
    }'

JWT Role-Based Access Control (RBAC)

For fine-grained access control, enable JWT-based RBAC:
config/config.yaml
service:
  jwt_rbac: true
JWT RBAC allows you to generate tokens with specific permissions for different users or applications. Documentation for generating JWT tokens is available in the Qdrant documentation.

TLS/SSL Configuration

Enable HTTPS and secure gRPC with TLS.

Generate Certificates

For development, create self-signed certificates:
mkdir -p tls

# Generate private key
openssl genrsa -out tls/key.pem 2048

# Generate certificate
openssl req -new -x509 -key tls/key.pem -out tls/cert.pem -days 365 \
    -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

# For cluster mode, create CA certificate
openssl genrsa -out tls/ca-key.pem 2048
openssl req -new -x509 -key tls/ca-key.pem -out tls/cacert.pem -days 365 \
    -subj "/C=US/ST=State/L=City/O=Organization/CN=Qdrant-CA"
For production, use certificates from a trusted Certificate Authority (CA) like Let’s Encrypt.

Enable TLS

config/config.yaml
service:
  enable_tls: true
  
tls:
  # Server certificate chain
  cert: ./tls/cert.pem
  
  # Server private key
  key: ./tls/key.pem
  
  # Certificate authority (for cluster mode)
  ca_cert: ./tls/cacert.pem
  
  # Auto-reload certificate every hour
  cert_ttl: 3600

Docker with TLS

docker run -p 6333:6333 -p 6334:6334 \
    -v $(pwd)/tls:/qdrant/tls:z \
    -e QDRANT__SERVICE__ENABLE_TLS=true \
    -e QDRANT__SERVICE__API_KEY=your_secret_key \
    qdrant/qdrant:latest

Connect with TLS

curl -k https://localhost:6333/collections \
    -H 'api-key: your_secret_api_key_here'
from qdrant_client import QdrantClient

client = QdrantClient(
    url="https://localhost:6333",
    api_key="your_secret_api_key_here",
    https=True,
    # For self-signed certificates
    verify=False
)

Client Certificate Verification

Require clients to present valid certificates:
config/config.yaml
service:
  enable_tls: true
  verify_https_client_certificate: true
  
tls:
  cert: ./tls/cert.pem
  key: ./tls/key.pem
  ca_cert: ./tls/cacert.pem
Client certificate verification requires all clients to have certificates signed by the CA specified in ca_cert.

Cluster Security

TLS for Inter-Node Communication

Secure communication between cluster nodes:
config/config.yaml
cluster:
  enabled: true
  p2p:
    port: 6335
    enable_tls: true

tls:
  cert: ./tls/cert.pem
  key: ./tls/key.pem
  ca_cert: ./tls/cacert.pem
All nodes in the cluster must have enable_tls set consistently. Mixed TLS/non-TLS configurations are not supported.

Docker Compose Cluster with TLS

docker-compose.yml
version: '3.7'

services:
  qdrant_node_1:
    image: qdrant/qdrant:latest
    environment:
      - QDRANT__CLUSTER__ENABLED=true
      - QDRANT__CLUSTER__P2P__PORT=6335
      - QDRANT__CLUSTER__P2P__ENABLE_TLS=true
      - QDRANT__SERVICE__ENABLE_TLS=true
      - QDRANT__SERVICE__API_KEY=cluster_secret_key
    volumes:
      - ./tls:/qdrant/tls:z
      - ./node1_storage:/qdrant/storage:z
    command: ./qdrant --uri 'https://qdrant_node_1:6335'

Network Security

Bind to Specific Interface

Restrict Qdrant to specific network interfaces:
config/config.yaml
service:
  # Bind only to localhost (no external access)
  host: 127.0.0.1
  
  # Or bind to specific internal IP
  host: 192.168.1.100

Firewall Rules

Configure firewall to restrict access:
# Allow HTTP/HTTPS from specific network
sudo ufw allow from 192.168.1.0/24 to any port 6333

# Allow gRPC from specific network
sudo ufw allow from 192.168.1.0/24 to any port 6334

# For cluster mode, allow P2P between nodes
sudo ufw allow from 192.168.1.10 to any port 6335
sudo ufw allow from 192.168.1.11 to any port 6335

Kubernetes Network Policies

Restrict pod-to-pod communication:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qdrant-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: qdrant
  policyTypes:
  - Ingress
  - Egress
  ingress:
  # Allow from application pods
  - from:
    - podSelector:
        matchLabels:
          app: my-application
    ports:
    - protocol: TCP
      port: 6333
  # Allow P2P from other Qdrant nodes
  - from:
    - podSelector:
        matchLabels:
          app: qdrant
    ports:
    - protocol: TCP
      port: 6335
  egress:
  # Allow to other Qdrant nodes
  - to:
    - podSelector:
        matchLabels:
          app: qdrant
    ports:
    - protocol: TCP
      port: 6335

Audit Logging

Track all API access with audit logs:
config/config.yaml
audit:
  enabled: true
  dir: ./storage/audit
  rotation: daily
  max_log_files: 7
  
  # Only enable if behind trusted proxy/load balancer
  trust_forwarded_headers: false

Audit Log Format

Audit logs are written as structured JSON:
{
  "timestamp": "2026-03-04T10:30:45.123Z",
  "client_ip": "192.168.1.100",
  "method": "POST",
  "path": "/collections/my_collection/points/search",
  "status": 200,
  "user_agent": "qdrant-client/1.0.0",
  "duration_ms": 45
}

Behind a Reverse Proxy

When running behind nginx or a load balancer:
config/config.yaml
audit:
  enabled: true
  # Trust X-Forwarded-For header for real client IP
  trust_forwarded_headers: true
Only enable trust_forwarded_headers when Qdrant is behind a trusted reverse proxy. Otherwise, clients can spoof their IP addresses.

Kubernetes Secrets

Store sensitive configuration in Kubernetes Secrets:
kubectl create secret generic qdrant-secrets \
  --from-literal=api-key=your_secret_api_key_here \
  --from-literal=read-only-api-key=your_read_only_key_here \
  --from-file=tls-cert=./tls/cert.pem \
  --from-file=tls-key=./tls/key.pem \
  --from-file=tls-ca=./tls/cacert.pem
Reference in your deployment:
env:
- name: QDRANT__SERVICE__API_KEY
  valueFrom:
    secretKeyRef:
      name: qdrant-secrets
      key: api-key

volumeMounts:
- name: tls-certs
  mountPath: /qdrant/tls
  readOnly: true

volumes:
- name: tls-certs
  secret:
    secretName: qdrant-secrets
    items:
    - key: tls-cert
      path: cert.pem
    - key: tls-key
      path: key.pem
    - key: tls-ca
      path: cacert.pem

Security Best Practices

Enable TLS for all external connections. Never transmit API keys over unencrypted HTTP in production environments.
Change API keys periodically and immediately if you suspect compromise. Use different keys for different environments.
Provide read-only API keys to analytics tools and dashboards to minimize risk.
Use firewalls and network policies to limit which hosts can connect to Qdrant. Bind to specific interfaces when possible.
Track all API access for security monitoring and compliance requirements.
Regularly update to the latest Qdrant version to receive security patches and improvements.
Harden the operating system, keep it patched, and follow security best practices for the infrastructure running Qdrant.
Generate strong, random API keys. Use a password manager or secrets management system.

Security Checklist

1

Generate Strong API Keys

Create random, complex API keys:
openssl rand -base64 32
2

Enable TLS/SSL

Configure TLS with valid certificates for all external connections.
3

Configure Firewall

Restrict network access to only trusted sources.
4

Enable Audit Logging

Track all API access for security monitoring.
5

Secure Inter-Node Communication

Enable TLS for cluster P2P communication.
6

Regular Updates

Keep Qdrant and dependencies up to date.

Next Steps

Configuration

Complete configuration reference

Distributed Mode

Secure cluster deployments

Kubernetes

Kubernetes security patterns

Docker

Docker security best practices

Build docs developers (and LLMs) love