Vector databases now hold the most sensitive text an organisation owns, chunked and embedded for retrieval, yet many are deployed with the security defaults of a developer prototype. Open source Qdrant accepts requests from anyone who can reach it until an API key is set, Milvus creates a root user with a published default password, and a pgvector table in a shared Postgres schema inherits whatever row level security (RLS) the team remembered to switch on. This guide covers how authentication, roles, tenancy, encryption, network exposure and logging work across Pinecone, Weaviate, Qdrant, Milvus and pgvector, and what a hardening baseline looks like. It is written for platform engineers, AppSec teams and security architects who own the retrieval layer behind RAG applications and AI agents. Retrieval pipeline design and prompt injection are covered in the RAG Security Guide; this page stays with the store itself.
Key takeaways
- Treat embeddings as the source data. OWASP LLM08:2025 lists embedding inversion as a real risk: an embedding of a contract or a patient note deserves the same classification as the document.
- Check the defaults before anything else. Self-hosted Qdrant ships with authentication off, Milvus ships with
root:Milvus, and Weaviate permits anonymous access if it is enabled; change these on day one. - Tenancy is an authorisation decision, not a query filter. Separate namespaces, tenants, collections or RLS policies enforced by the store beat a metadata filter that the application must never forget.
- The application's key is the crown jewel. Most vector stores are reached through one service credential with read and write rights to every collection; scope it, vault it and rotate it like any other privileged NHI.
- Audit logging is usually off or a paid tier. Qdrant's
audit.enableddefaults to false and Pinecone audit logs need the Enterprise plan or HIPAA add-on, so plan detection before an incident, not after.
How identity and access work in vector databases
Vector stores grew out of search engines and research projects, so their access models differ widely. The table summarises the mechanisms each product documents. Versions matter: several features below arrived recently, so check the release you actually run.
| Product | Authentication | Authorisation model | Default posture (self-hosted) |
|---|---|---|---|
| Pinecone (managed) | Project API keys; console users with SSO on Standard and Enterprise plans | RBAC: users, API keys and service accounts are principals with roles at project or organisation level | Managed service: every request needs a valid project key |
| Weaviate | API keys (AUTHENTICATION_APIKEY_ENABLED), OIDC, optional anonymous access | RBAC from v1.29 with built-in root and viewer roles, or the older admin list (cannot be combined) | Anonymous access possible; documentation discourages it outside development |
| Qdrant | api_key (full access), read_only_api_key, JWT tokens signed with the API key | JWT RBAC (jwt_rbac, v1.9.0+): global read or manage, or per-collection r/rw | Authentication off: "accepts requests from anyone who can reach it" (Qdrant Cloud enables it by default) |
| Milvus | Username and password, passed as a user:password token | RBAC with users, roles, privileges and privilege groups at instance, database and collection level | Enabled only when common.security.authorizationEnabled is true; default root password is Milvus |
| pgvector | PostgreSQL roles and pg_hba.conf methods | GRANT privileges plus row level security policies | Inherits the Postgres instance; RLS off on every new table |
Three design points follow from this. First, API keys in Weaviate and Qdrant are static shared secrets configured in environment variables or config files, so whoever can read the deployment manifest can read the key. Second, only some products bind access to an external identity provider: Weaviate supports OIDC directly, Pinecone supports SSO for console users, and pgvector inherits whatever Postgres authentication you configure. Third, the authorisation unit differs (namespace, tenant, collection, row), and your tenancy design must match the unit the store can enforce.
Tenancy and isolation options
| Pattern | Where it is documented | Isolation strength | Trade-off |
|---|---|---|---|
| Namespace per tenant | Pinecone serverless indexes | Pinecone describes namespaces as physically isolated; offboarding is a namespace delete | Namespace limits depend on plan; the API key still reaches every namespace in the project |
| Tenant per collection shard | Weaviate multi-tenancy with tenant permissions | RBAC can scope by collection name and tenant name filters | Creating a collection does not grant tenant creation; roles must be designed per tenant pattern |
| Collection per tenant with scoped tokens | Qdrant JWT RBAC, Milvus collection privileges | Enforced by the server per collection | Collection sprawl; Qdrant tokens all die if the signing key rotates |
| Row level security on a shared table | PostgreSQL RLS with pgvector | Enforced in the database, default deny once enabled | Owner and BYPASSRLS roles skip policies unless FORCE ROW LEVEL SECURITY is set |
| Metadata filter in a shared space | All products | Weakest: depends on every query including the filter | Cheap and flexible; one missing filter leaks across tenants (OWASP LLM08 scenario 2) |
Decision guidance: for customer-facing SaaS with contractual isolation duties, use a server-enforced boundary (namespace, tenant, collection or RLS) and treat metadata filtering as a relevance tool only. For an internal knowledge assistant where everyone may read the corpus, a shared collection is acceptable, but document-level permissions from the source system (SharePoint, Confluence, a ticketing system) still need to be carried into the index and enforced at query time. Small teams usually do best with a managed service and one namespace or collection per tenant; large organisations with many business units often run one store per data classification, so that a regulated corpus never shares a key with a general one. The Multi-Tenant SaaS Authorisation Guide covers tenant context propagation in the application tier.
pgvector specifics: enable RLS with ALTER TABLE ... ENABLE ROW LEVEL SECURITY, then add FORCE ROW LEVEL SECURITY so the table owner is also bound. PostgreSQL documents that superusers and roles with BYPASSRLS always bypass policies, so the application must not connect as either. Note a relevance side effect: pgvector applies WHERE conditions after the approximate index scan, so with HNSW and the default hnsw.ef_search of 40, a policy that matches a small share of rows can return very few results. Teams that "fix" this by disabling RLS have traded security for recall; use iterative index scans (hnsw.iterative_scan) or partitioning instead. See the PostgreSQL Security Guide.
Admin roles and privileged access
- Qdrant: the
api_keygrants full access and also signs every JWT. Anyone holding it can mint tokens with any claim. Keep it out of application pods where possible: give applications short-lived JWTs with anexpclaim and per-collection access, and reserve the master key for an issuing service. Usealt_api_key(v1.17.0+) to rotate without downtime, remembering that the documentation warns that changingapi_keyinvalidates all existing tokens. - Milvus: change the
rootpassword withupdate_password()immediately after enabling authentication, create named administrator users, and keepcommon.security.superUsersempty unless you need a recovery path, because listed users can reset passwords without the old one. - Weaviate: assign the
rootrole only throughAUTHORIZATION_RBAC_ROOT_USERSto named administrators, give analysts theviewerrole, and build custom roles for applications that cover only the collections, tenants and data object actions they need. Backup permissions deserve separate attention: a backup role can copy the whole corpus. - Pinecone: organisation owners can enable audit logs and manage SSO; project roles govern who can create indexes and keys. Require SSO for your domain, set a low default role for new teammates, and review organisation owner membership quarterly.
- pgvector: separate the schema owner (migrations), the application role (DML only, no
BYPASSRLS) and the human DBA role. The Database Credential and Access Security Guide covers the Postgres side in depth.
Human administrator access to a vector store is privileged access to every document in it. Put it behind your PAM workflow with just-in-time elevation and session recording where the product supports it.
Integrations, API tokens and service accounts
A typical RAG deployment has at least three non-human identities touching the store: the ingestion pipeline that writes embeddings, the retrieval service or agent that queries, and a backup or replication job. Each needs a different scope.
| Identity | Needs | Should not have | Mechanism |
|---|---|---|---|
| Ingestion pipeline | Write to specific collections or namespaces | Delete collections, read other tenants, manage roles | Weaviate custom role; Qdrant JWT with rw on named collections; Milvus collection privileges; Postgres INSERT/UPDATE grant |
| Retrieval service or AI agent | Read the collections for the current user or tenant | Write or delete; cross-tenant reads | Qdrant read_only_api_key or JWT with r; Weaviate viewer or custom role; RLS keyed on tenant |
| Backup job | Snapshot or backup rights | Interactive query rights | Dedicated role with backup permission only |
| Embedding model provider key | Call the embedding API | Store access | Separate secret, often configured as a module key in the store |
- Vault the keys: inject vector store keys from a secrets manager at runtime instead of baking them into container images or
.envfiles committed to Git. See the Secrets Management Guide and the API Key Management Guide. - Do not let the agent hold the write key: an AI agent that can upsert into its own knowledge base can be steered by prompt injection into poisoning it (ATLAS AML.T0070 RAG Poisoning). Keep ingestion as a separate, reviewed pipeline.
- Watch for keys stored inside the corpus: ATLAS AML.T0082 RAG Credential Harvesting describes adversaries querying a RAG store for credentials that were ingested with source documents. Scan documents for secrets before embedding them.
- Enforce user context end to end: when the retrieval service queries on behalf of a user, pass the user or tenant identity and enforce it in the store (tenant filter in a JWT, RLS session variable, namespace selection) rather than trusting the model to ignore results. The AI Agent Authorisation Guide covers delegated access patterns.
Logging and detection
Retrieval logs are the only way to answer "which documents did the assistant see for this user?" after an incident. OWASP LLM08 recommends detailed immutable logs of retrieval activity. Support varies:
- Pinecone: audit logs record user and API actions, captured every 30 minutes as JSON; organisation owners enable them, and they require the Enterprise plan or HIPAA add-on.
- Weaviate: when RBAC is enabled, authorisation decisions are logged for audit.
- Qdrant: an audit log exists but
audit.enableddefaults to false. Setaudit.trust_forwarded_headersto true only behind a trusted proxy, or client IPs can be spoofed. - Milvus and pgvector: rely on platform logging; for Postgres use
log_connections, role-level statement logging or the pgAudit extension, and log at the application tier which document IDs were returned.
Detections worth building:
- A read-only identity attempting writes or deletes (scope drift or a stolen key used for poisoning).
- Queries from a retrieval key outside its normal source network or workload identity.
- High-volume sequential scrolling or export of a collection, consistent with ATLAS AML.T0085.000 Data from AI Services: RAG Databases.
- Ingestion of documents outside the approved pipeline, or sudden growth in a collection.
- Collection, tenant or role changes outside a change window.
- Requests carrying expired or unknown JWTs against Qdrant, which indicate key rotation gaps or forging attempts.
Metrics: percentage of vector stores with authentication enforced and anonymous access disabled; percentage of application identities that are least-privilege (read-only or collection-scoped); mean age of vector store API keys; percentage of collections with retrieval logging retained for at least your incident lookback period; number of tenants sharing a store without a server-enforced boundary (target zero for customer data).
Hardening baseline
- Inventory first: find every vector store, including Chroma or Qdrant containers started by data scientists, pgvector extensions (
CREATE EXTENSION vectoris per database), and managed indexes. Record owner, data classification and network exposure. - Close exposure: bind self-hosted services to private interfaces (Qdrant
service.host), never expose Qdrant's internal port 6335, keep 6333/6334 and Milvus 19530 behind a private network or gateway, and use Pinecone Private Endpoints (AWS PrivateLink or Azure Private Link) for production indexes. - Enable authentication and change defaults: set Qdrant
api_key; set MilvusauthorizationEnabledand rotate the root password; set WeaviateAUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=falseand do not useAUTHENTICATION_OIDC_SKIP_CLIENT_ID_CHECK. - Encrypt in transit: Qdrant
service.enable_tlswithtls.certandtls.key, pluscluster.p2p.enable_tlsfor peers. Qdrant's documentation states that sending an API key over an unencrypted channel is insecure. Pinecone uses TLS 1.2 for HTTPS and gRPC. - Encrypt at rest with keys you control where required: Pinecone encrypts with AES-256 and offers customer-managed keys through AWS KMS; for self-hosted stores, encrypt volumes and snapshot storage. See the Database and Storage Encryption Guide.
- Introduce least privilege: enable Weaviate RBAC or Qdrant JWT RBAC or Milvus roles, issue separate identities for ingestion, retrieval and backup, and enforce tenancy server-side.
- Turn on logging and ship it to the SIEM before go-live.
- Test, then roll out: enable authentication in a staging cluster first, run the application's retrieval test suite, then roll to production with both old and new keys valid (Qdrant
alt_api_key) so you can roll back by reverting configuration rather than reopening the store.
Common misconfigurations
- Development container promoted to production: a Qdrant or Weaviate instance started without a key, reachable on a cloud IP. Open AI data stores are a recurring breach pattern: the DeepSeek database exposure leaked chat logs and secrets from an unauthenticated ClickHouse database.
- RLS never enabled on a Postgres-backed store: in the Moltbook database exposure, a publishable Supabase key in client JavaScript gave full database access because row level security was off, exposing about 1.5 million agent API tokens. A pgvector table without RLS behind the same pattern exposes every embedding and source chunk.
- Tenant isolation by metadata filter only: a single code path that omits the tenant filter returns another customer's chunks.
- One admin key everywhere: ingestion, retrieval, notebooks and CI share the Qdrant master key, so any leak allows writes and token minting.
- Unreviewed backups: snapshots copied to object storage with broad read access, outside the store's RBAC entirely.
- Deletion that does not delete: a data subject or customer is offboarded in the source system but their chunks remain in the index because no deletion job maps source IDs to vector IDs.
Framework mapping
| Control area | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | CIS Controls v8.1 | ISO/IEC 27001:2022 Annex A | Threat reference |
|---|---|---|---|---|---|
| Authentication and key management | IA-5 | PR.AA-05 | 4.7 Manage default accounts | A.5.17 | AML.T0082 |
| Least privilege and tenancy | AC-3, AC-6 | PR.AA-05 | 3.3 Configure data access control lists | A.5.15, A.8.3 | OWASP LLM08; AML.T0085.000 |
| Encryption | SC-8, SC-28 | PR.DS-01, PR.DS-02 | 3.10, 3.11 | A.8.24 | AML.M0012 Encrypt Sensitive Information |
| Network exposure | SC-7 | PR.PS-01 | 4.4, 12.2 | A.8.20, A.8.22 | T1190 |
| Logging and detection | AU-2, AU-12 | DE.CM-09 | 8.2 Collect audit logs | A.8.15, A.8.16 | AML.T0024.001 Invert AI Model |
Practitioner checklist
- Inventory every vector store and pgvector database with owner, classification and exposure.
- Confirm authentication is enforced and anonymous access is off on every instance; rotate any default credential.
- Remove public exposure: private networking or private endpoints, no public internal cluster ports.
- Enforce tenancy in the store (namespace, tenant, collection or RLS with FORCE), not only in query filters.
- Issue separate least-privilege identities for ingestion, retrieval and backup; keep master keys out of applications.
- Store vector store keys in a secrets manager and rotate them on a schedule, using dual-key rotation where supported.
- Scan documents for secrets and sensitive data before embedding them.
- Enable audit or retrieval logging, forward it to the SIEM and alert on scope drift and bulk export.
- Build a deletion path from source document IDs to vector IDs and test it.
Standards and references
- OWASP: Top 10 for LLM Applications 2025 (LLM08 Vector and Embedding Weaknesses)
- MITRE ATLAS: Data from AI Services
- Qdrant: Security
- Weaviate: Role-based access control
- Milvus: Authenticate user access
- Pinecone: Security overview
- PostgreSQL: Row security policies
- pgvector: Open-source vector similarity search for Postgres
Related NHI Mgmt Group resources: RAG Security Guide · OWASP LLM Top 10 LLM08 Vector and Embedding Weaknesses Guide · AI Agent Memory Security Guide · Secrets Management Guide