Data as of Sep 20, 2026 · Based on 351 AI responses from ChatGPT Search and Google AI Mode · See how Parse measures this
For handling complex, hierarchical user permissions, three solutions stand out based on specific architectural strengths. Qdrant is highly recommended for its fast performance when filtering complex, nested metadata.
Weaviate is best if your permissions rely on knowledge graph relationships or need to combine keyword and vector search.
Milvus is the top choice for massive enterprise-scale RAG systems requiring deep distributed security controls.
Brands AI recommends here
Named in 84% of answers
Ideal for projects requiring fast metadata filtering. Its use of Rust allows for efficient handling of complex, nested permission structures, making it a strong choice when performance is a priority for real-time access checks.
Named in 72% of answers
Recommended for large enterprise needs. Its distributed system is built for massive, multi-tenant datasets (billions of vectors) and provides granular, database-level security controls for high-security, professional environments.
Named in 71% of answers
Best for relationship-based permissions. It natively understands connections between data entities like a knowledge graph, making it effective for complex hierarchies where access is tied to these interconnected data relationships.
Named in 70% of answers
For **complex, hierarchical permissions in semantic search**, I’d evaluate the database less on “does it have ACLs?” and more on whether its **metadata filter language can express your authorization predicate efficiently and safely**. ### How the main options compare Database | Advanced metadata filtering |…
For complex, hierarchical permissions in semantic search, I’d evaluate the database less on “does it have ACLs?” and more on whether its metadata filter language can express your authorization predicate efficiently and safely.
| Database | Advanced metadata filtering | Hierarchical/compound ACL modeling | Tenant isolation | Built-in RBAC | Fit for complex ACL filtering |
|---|---|---|---|---|---|
| Qdrant | Very strong | Very strong — nested JSON, recursive AND/OR/NOT | Strong | Primarily application-level for document ACLs | Strong |
| Milvus | Strong | Strong scalar filtering | Strong | Yes, at database/collection levels | Strong |
| Weaviate | Strong | Strong | Strong multi-tenancy | Authorization capabilities | Strong |
| Pinecone | Strong | Good for relatively simple predicates | Strong namespaces/metadata patterns | Application/API-layer oriented | Good |
| OpenSearch | Very strong | Very strong | Strong | Very strong | Strong if you want search + security controls |
For your specific requirement, Qdrant is particularly well suited to expressing complicated ACL predicates directly in vector-search filters. Its payload is arbitrary JSON, and filters support recursively nested Boolean conditions plus nested-object filtering.
For example, you can model something conceptually like:
{
"tenant_id": "acme",
"acl": {
"users": ["u123"],
"groups": ["engineering"],
"roles": ["manager"],
"departments": ["finance"],
"min_clearance": 3
},
"classification": "internal"
}
and construct a query along the lines of:
tenant_id = current_tenant
AND classification <= user's_clearance
AND (
user_id IN user's_users
OR group_id IN user's_groups
OR role IN user's_roles
)
Qdrant supports recursive Boolean filter composition and nested payload objects, which maps naturally onto these kinds of authorization expressions.
It also has explicit multitenancy mechanisms: payload-based tenant partitioning, tenant-aware indexing, and dedicated shards for tenants requiring stronger physical isolation.
Don't treat vector-database metadata filtering itself as your security boundary. I'd make your authorization service the source of truth and have it produce a constrained filter for the vector query.
A robust architecture is:
User
↓
Identity / authorization service
↓
Effective permissions
↓
ACL → vector-db filter
↓
Vector search
↓
Authorized results
This avoids putting arbitrary authorization logic in the client and makes it possible to enforce the same permissions across your vector DB, SQL DB, object storage, etc.
Milvus is worth serious consideration if your hierarchy is primarily tenant/database/collection-oriented. Its current multitenancy model includes database-, collection-, partition-, and partition-key-level isolation; database and collection strategies also support RBAC. Partition-key isolation can scale to very large tenant counts.
If your ACLs involve things like:
“User belongs to group A, which inherits permissions from groups B and C, except documents explicitly denied to them, while department-level permissions override project-level restrictions” then the real question isn't merely which DB has the richest filter syntax. You need to decide where ACL inheritance is evaluated. Usually I'd resolve that hierarchy into an effective permission set first, then give the vector DB a relatively flat, indexed predicate.
For that architecture, Qdrant gives you an especially expressive filtering layer, while Milvus provides a stronger set of native database-level tenancy/RBAC primitives. Qdrant's documentation also specifically recommends payload indexes for fields used in filters and provides mechanisms designed for filtered vector-search performance.
If you tell me whether your ACL hierarchy is RBAC, ABAC, group inheritance, resource inheritance, or a combination, I can sketch the data model and query strategy for Qdrant vs. Milvus vs. Pinecone.
When handling complex, hierarchical user permissions (like nested group inheritances, multi-tenant organization structures, or fine-grained ACL arrays) alongside semantic search, **Qdrant** currently offers the best native support and performance architecture. The primary contenders stack up as follows for advanced…
When handling complex, hierarchical user permissions (like nested group inheritances, multi-tenant organization structures, or fine-grained ACL arrays) alongside semantic search, Qdrant currently offers the best native support and performance architecture.
The primary contenders stack up as follows for advanced metadata filtering and ACL integration:
nested conditions). If your ACL structure requires matching objects inside arrays (e.g., matching a user against a list of permitted department/role objects), Qdrant handles this natively without breaking index efficiency.allowed_groups containing user groups) very fast. However, its capability for deeply nested hierarchical logic is less flexible than Qdrant’s explicit JSON payload schema, forcing you to flatten your permission hierarchies into simple string arrays during ingestion.Regardless of the database you pick, implement early-binding ACL filtering . At ingestion, tag every vector chunk with a payload array of authorized roles or user IDs (e.g., acl: {groups: ["eng", "mgmt"], tenants: ["org-A"]} ). Then, dynamically construct the database filter query using the user's active credentials at search time. Qdrant's engine handles these multi-condition boolean filters (should/must combined with nested lookups) with the lowest latency degradation when filtering out unauthorized chunks.
To help narrow down the ideal fit, could you share:
For **complex, hierarchical permissions in semantic search**, I’d pick **Weaviate** overall. The key distinction is that you need both **rich metadata filtering** *and* an authorization model—not merely a vector DB that lets you attach an `acl` field. Database | Metadata filtering | Native ACL/RBAC | Multi-tenancy |…
For complex, hierarchical permissions in semantic search, I’d pick Weaviate overall.
The key distinction is that you need both rich metadata filtering and an authorization model—not merely a vector DB that lets you attach an acl field.
| Database | Metadata filtering | Native ACL/RBAC | Multi-tenancy | Fit for hierarchical ACLs |
|---|---|---|---|---|
| Weaviate | Excellent | Yes — RBAC | Excellent | Best overall |
| Qdrant | Excellent | More application-driven | Excellent | Very good |
| Pinecone | Very good | Mostly application-driven | Excellent via namespaces | Good |
| Milvus | Very good | Primarily application/schema-driven | Good | Good |
Weaviate combines structured filters with vector search using pre-filtering, so authorization predicates can participate in candidate retrieval rather than simply filtering a large result set afterward. Its current filtering engine also uses the ACORN strategy by default starting with v1.34.
More importantly for your use case, Weaviate has native RBAC. Roles can have permissions over collections, tenants, and operations, with constraints such as collection-name filters.
It also has first-class multi-tenancy, with tenant isolation at the shard level.
For example, your document metadata could conceptually look like:
{
"tenant_id": "acme",
"department": "engineering",
"classification": "confidential",
"allowed_roles": ["engineer", "manager"],
"allowed_groups": ["platform", "search-team"],
"owner_id": "user123",
"parent_acl": "dept-engineering"
}
Then your application translates the authenticated user's permissions into a single retrieval filter:
tenant_id == "acme"
AND classification <= user's_clearance
AND (
allowed_roles CONTAINS user's_role
OR allowed_groups INTERSECTS user's_groups
OR owner_id == user_id
)
For genuinely hierarchical ACLs—e.g. organization → department → team → project → document—I'd generally keep the authoritative permission graph in your identity/authorization system, and materialize the effective permissions needed for retrieval into vector metadata.
That's important: don't make the vector DB your source of truth for authorization. Treat the vector filter as an enforcement layer for retrieval, while your IAM/authorization service remains authoritative.
Qdrant is arguably the better choice if you're comfortable implementing authorization yourself. Its payload filtering is extremely flexible, and its multitenancy documentation explicitly supports partitioning a shared collection using tenant payload filters, dedicated shards, or a hybrid approach.
So my ranking for your specific requirement would be:
Bottom line: if "complex hierarchical ACLs must be enforced as part of semantic retrieval" is a primary architectural requirement, I'd prototype Weaviate first, with your authorization service generating the retrieval predicates rather than trying to encode the entire permission hierarchy directly into the vector database.
Weaviate combines structured filters with vector search using pre-filtering, so authorization predicates can participate in candidate retrieval rather than simply filtering a large result set afterward. Its current filtering engine also uses the ACORN strategy by default starting with v1.34.
More importantly for your use case, Weaviate has native RBAC. Roles can have permissions over collections, tenants, and operations, with constraints such as collection-name filters.
It also has first-class multi-tenancy, with tenant isolation at the shard level.
For example, your document metadata could conceptually look like:
{
"tenant_id": "acme",
"department": "engineering",
"classification": "confidential",
"allowed_roles": ["engineer", "manager"],
"allowed_groups": ["platform", "search-team"],
"owner_id": "user123",
"parent_acl": "dept-engineering"
}
Then your application translates the authenticated user's permissions into a single retrieval filter:
tenant_id == "acme"
AND classification <= user's_clearance
AND (
allowed_roles CONTAINS user's_role
OR allowed_groups INTERSECTS user's_groups
OR owner_id == user_id
)
For genuinely hierarchical ACLs—e.g. organization → department → team → project → document—I'd generally keep the authoritative permission graph in your identity/authorization system, and materialize the effective permissions needed for retrieval into vector metadata.
That's important: don't make the vector DB your source of truth for authorization. Treat the vector filter as an enforcement layer for retrieval, while your IAM/authorization service remains authoritative.
Qdrant is arguably the better choice if you're comfortable implementing authorization yourself. Its payload filtering is extremely flexible, and its multitenancy documentation explicitly supports partitioning a shared collection using tenant payload filters, dedicated shards, or a hybrid approach.
So my ranking for your specific requirement would be:
When handling complex, hierarchical user permissions and Access Control Lists (ACLs) in semantic search, **no vector database natively manages dynamic corporate permission graphs out of the box** (like active directory, nested group inheritances, or real-time ACL mutations). Instead, vector databases handle this via…
When handling complex, hierarchical user permissions and Access Control Lists (ACLs) in semantic search, no vector database natively manages dynamic corporate permission graphs out of the box (like active directory, nested group inheritances, or real-time ACL mutations).
Instead, vector databases handle this via advanced metadata payload filtering , where you denormalize and attach permission tokens (e.g., allowed_groups: ["dept_A", "team_X"] ) directly to the vectors.
The leading contenders for handling the underlying filtering performance at scale rank as follows:
AND/OR conditions checking array memberships like "is user in group A and clearance level≥3 is greater than or equal to 3≥3 "), Qdrant handles high-selectivity filtering without severe performance degradation. It also supports payload indexing and custom shard key selectors for multi-tenancy.$in ). However, it enforces strict limits on metadata size per vector (typically 40KB) and limits on array sizes inside filter statements (e.g., 10,000 values per $in clause). If your hierarchical expansion yields massive group ID arrays for a single user, you can hit these ceilings faster than self-hosted solutions.Regardless of which database you select, implement Early Binding with Denormalized Payloads:
acl: ["tenant_1", "dept_finance", "user_42"]).must match any of user's ACLs).To help narrow down the optimal choice, could you share:
For **complex, hierarchical permissions in semantic search**, I would not choose purely on “vector performance.” The hard part is ensuring **authorization constraints are applied before results are returned**, not retrieving broadly and filtering afterward. A post-filtering design can leak information through result…
For complex, hierarchical permissions in semantic search, I would not choose purely on “vector performance.” The hard part is ensuring authorization constraints are applied before results are returned, not retrieving broadly and filtering afterward. A post-filtering design can leak information through result counts, rankings, snippets, or timing.
My ranking for ACL-heavy enterprise search:
| Vector DB | Metadata filtering | ACL fit | Best fit |
|---|---|---|---|
| Weaviate | Excellent | Best overall | Enterprise search with RBAC + document-level ACL metadata |
| Qdrant | Excellent | Very flexible | Custom authorization models and complex payload rules |
| pgvector | Excellent (via SQL) | Excellent if you already have relational ACLs | Apps where Postgres is the source of truth |
| Milvus | Strong | Good | Very large-scale vector workloads |
| Pinecone | Strong | Good for simpler models | Managed deployments with external auth |
Anjali Rajawat Anjali Rajawat## Best overall: Weaviate
For your specific requirement—hierarchical users, groups, departments, projects, and document ACLs—Weaviate is probably the strongest choice.
Reasons:
AND/OR/NOT) and structured metadata constraints. A common enterprise pattern would be:
{
"document_id": "doc-123",
"tenant": "acme",
"org": "engineering",
"groups": [
"platform-team",
"security-reviewers"
],
"allowed_roles": [
"manager",
"engineer"
],
"project_ids": [
"search-platform"
],
"classification": "internal"
}
Then your application resolves the user's effective permissions:
User
└── Organization
└── Department
└── Team
└── Project
└── Document ACL
and converts that into a vector query filter.
Qdrant is arguably the strongest metadata-filtering engine if you want to build the authorization model yourself. Its payload model is very flexible for nested JSON, arrays, and boolean conditions.
Example:
{
"must": [
{
"key": "tenant_id",
"match": {
"value": "acme"
}
}
],
"should": [
{
"key": "group_ids",
"match": {
"any": [
"engineering",
"admins"
]
}
}
]
}
I would pick Qdrant if:
For enterprise semantic search, I would usually separate concerns:
Identity Provider
|
v
Authorization Engine
(Okta / Azure AD / OPA / custom)
|
v
Effective ACL calculation
|
v
Vector DB filtered query
|
v
LLM / RAG response
The vector database should enforce the final retrieval boundary, but it should not become your source of truth for authorization policy.
For a typical enterprise knowledge base with AD/LDAP groups, document sharing, and nested permissions, I would start with Weaviate + an external authorization layer.
Qdrant is arguably the strongest metadata-filtering engine if you want to build the authorization model yourself. Its payload model is very flexible for nested JSON, arrays, and boolean conditions.
Example:
{
"must": [
{
"key": "tenant_id",
"match": {
"value": "acme"
}
}
],
"should": [
{
"key": "group_ids",
"match": {
"any": [
"engineering",
"admins"
]
}
}
]
}
I would pick Qdrant if:
For enterprise semantic search, I would usually separate concerns:
Identity Provider
|
v
Authorization Engine
(Okta / Azure AD / OPA / custom)
|
v
Effective ACL calculation
|
v
Vector DB filtered query
|
v
LLM / RAG response
The vector database should enforce the final retrieval boundary, but it should not become your source of truth for authorization policy.
For a typical enterprise knowledge base with AD/LDAP groups, document sharing, and nested permissions, I would start with Weaviate + an external authorization layer.
When handling hierarchical user permissions and complex Access Control Lists (ACLs) in a vector database, **Qdrant** and **Milvus** stand out as the strongest contenders, though they approach the problem differently. For fine-grained, high-performance metadata filtering and nested hierarchical ACLs, **Qdrant**…
When handling hierarchical user permissions and complex Access Control Lists (ACLs) in a vector database, Qdrant and Milvus stand out as the strongest contenders, though they approach the problem differently.
For fine-grained, high-performance metadata filtering and nested hierarchical ACLs, Qdrant generally provides the best developer experience and architectural efficiency.
acl.groups or acl.departments.engineering ). You can explicitly create payload indexes on these nested fields to make deep, multi-condition boolean logic (must, should, must_not ) blazing fast.reader_ids ), Milvus executes this efficiently at scale using robust bitmap filtering.$in or $or clauses can become cumbersome and run into payload size limits depending on how large your user-group expansions get.No matter which database you choose, do not store raw hierarchical trees inside the vector metadata at query time . Instead, flatten the hierarchy during ingestion:
allowed_tokens: ["org_123", "dept_eng", "user_991"]).$in (or Qdrant MatchAny ) operator:json```
{
"filter": {
"must": [
{ "key": "allowed_tokens", "match": { "any": ["org_123", "dept_eng", "user_991"] } }
]
}
}Use code with caution.
3. **Index the Field:** Explicitly create an index on `allowed_tokens` in Qdrant or Milvus to ensure O(1) or logarithmic lookup speeds during vector traversal.
To help narrow down the ideal fit, could you share:
- **Roughly how many vectors** you plan to store?
- **How deep or complex** the permission hierarchy goes (e.g., flat role-based vs. inherited folder/document-level ACLs)?
When handling complex, hierarchical user permissions (like nested groups, organizational units, or inheritance) alongside semantic search, **no single vector database natively "solves" ACLs out of the box** by replacing an authorization engine. Vector databases are optimized for high-dimensional math, not graph-based…
When handling complex, hierarchical user permissions (like nested groups, organizational units, or inheritance) alongside semantic search, no single vector database natively "solves" ACLs out of the box by replacing an authorization engine. Vector databases are optimized for high-dimensional math, not graph-based permission trees.
Instead, the "best" choice depends on how effectively the vector database handles high-cardinality payload indexing, complex boolean/array filtering (i n i n𝒊𝒏, a n d a n d𝒂𝒏𝒅, o r o r𝒐𝒓), and fast pre-filtering without tanking search latency.
The top contenders for advanced metadata filtering and ACL handling stand out for distinct reasons:
Qdrant treats payload (metadata) filtering as a first-class citizen rather than an afterthought.
must, should, must_not ), array containment checks (match any/match all ), and integer/string ranges. If your ACL model involves tagging chunks with an array of allowed role_ids or group_ids (e.g., allowed_groups: ["dept_fin", "region_us", "tier_1"] ), Qdrant can evaluate whether a user's permission array intersects with the chunk's ACL array extremely fast.Pinecone handles permissions via a hybrid approach: Namespaces for strict multi-tenancy or Metadata Filters for fine-grained lists.
$in operator. However, Pinecone has limits on array sizes in a single filter expression (capped at 10,000 values in an $in or $nin operator).Weaviate offers explicit Named Tenants at the physical/shard level, which changes how hard isolation is managed.
The Architectural Reality Check: Pre-filter vs. ReBAC
Regardless of the database you choose (Qdrant, Pinecone, Weaviate, or Milvus), implementing hierarchical user permissions forces an architectural choice:
Engineering -> Frontend -> Senior Devs , every chunk gets tagged with metadata like groups: ["company_all", "eng", "eng_frontend", "eng_frontend_seniors"] . At query time, you pass the user's pre-computed group list into the vector database filter. Qdrant handles this style of high-cardinality array matching natively with the best performance.If you can share:
I can recommend whether a pure metadata-array approach in Qdrant or a hybrid ReBAC pattern fits your team best.
If **complex hierarchical permissions / ACLs** are a first-class requirement for semantic search, I’d pick **Weaviate** among the major vector databases I checked. | Database | Metadata filtering | Built-in authorization / ACL model | Hierarchical ACL fit | |---|---|---|---|
If complex hierarchical permissions / ACLs are a first-class requirement for semantic search, I’d pick Weaviate among the major vector databases I checked.
| Database | Metadata filtering | Built-in authorization / ACL model | Hierarchical ACL fit |
|---|---|---|---|
| Weaviate | Strong | RBAC + tenant-level permissions | Best |
| Qdrant | Excellent payload filters | Mostly application-enforced | Very good, but you build ACL logic |
| Pinecone | Good metadata filters | Namespaces/API-level controls | Good for simpler tenant isolation |
| Milvus | Excellent scalar filtering + partition keys | More infrastructure/partition oriented | Good, but ACL logic is largely external |
Weaviate has actual RBAC, with roles assigned to users and permissions controlling operations and resources. Its permissions can be scoped to collections and tenants, and it supports filters such as collection/tenant name patterns.
It also has native multi-tenancy, with each tenant isolated on its own shard, so tenant boundaries don't depend solely on an application-side filter.
That makes a model such as:
Organization
├── Division A
│ ├── Team 1
│ └── Team 2
└── Division B
└── Team 3
easier to map onto a combination of tenant isolation + RBAC + metadata filters.
None of these databases should be treated as a complete enterprise document-ACL engine. If your requirement is something like:
Alice can access documents inherited from her organization, department, team, project, and explicit grants, with deny-overrides-allow and dynamically changing group membership.
I'd keep the source of truth for authorization in your identity/authorization system and derive an authorization filter for the vector query.
For example:
User
↓
Identity / authorization service
↓
Allowed tenant IDs
Allowed org/project IDs
Allowed security labels
↓
Vector DB metadata filter
↓
Semantic search
This is generally safer than encoding your entire permission hierarchy inside the vector database.
Choose Weaviate if native authorization capabilities are a major selection criterion.
Choose Qdrant if your application already has a sophisticated authorization service and you primarily want a powerful, flexible filtering engine. Qdrant's payload filtering and multitenancy mechanisms are particularly strong; its documentation describes tenant partitioning via payload fields, dedicated shards, or tiered multitenancy.
Choose Pinecone if you prioritize managed-service simplicity and your ACL model is relatively straightforward. Its metadata filtering supports compound filter expressions, but authorization itself is less of a built-in hierarchical ACL system.
Choose Milvus when very large-scale deployments and partition-based tenant isolation/performance are priorities. Its partition-key mechanism can restrict searches to the relevant tenant partitions.
Bottom line: Weaviate for the strongest out-of-the-box authorization story; Qdrant for maximum application-controlled ACL flexibility.
When handling complex, hierarchical user permissions (like nested groups, organizational units, or inherited ACLs) in a vector search environment, no dedicated vector database natively replaces a full authorization engine (like OpenFGA or SpiceDB). Instead, you implement **Fine-Grained Access Control (FGAC)** via…
When handling complex, hierarchical user permissions (like nested groups, organizational units, or inherited ACLs) in a vector search environment, no dedicated vector database natively replaces a full authorization engine (like OpenFGA or SpiceDB). Instead, you implement Fine-Grained Access Control (FGAC) via metadata/payload filtering during the Approximate Nearest Neighbor (ANN) search.
The top vector databases handle this through specific strengths in payload indexing, array handling, and filtering performance.
Top Contenders for Advanced Metadata Filtering & ACLs
allowed_groups: ["team_a", "dept_x", "company_root"] array on a vector point) and checking if a user’s permission set overlaps with that array using match: { any: [...] }.must, should, must_not ) natively in its query filter API. Payload indices can be created on any metadata field to ensure filtering doesn't degrade search latency, even with high cardinality user IDs.expr ) during vector searches.$in or $contains.The Recommended Architecture Pattern
Regardless of which database you pick, do not compute or store raw hierarchical trees inside the vector database. The standard, production-proven pattern for hierarchical ACL + vector search relies on a pre-retrieval flattening pipeline:
Folder C , which is under Department B , which is under Company A , the ingestion pipeline resolves all ancestor groups and assigns an explicit, flattened array to the vector metadata:acl_groups: ["company_a", "department_b", "folder_c"].any or $in filter into the vector search query (e.g., *Match vectors where acl_groups intersect with [user_id, group_1, group_2] *).If you want to narrow this down, tell me:
I can recommend the ideal schema design and exact filter query structure for your setup.
For **complex, hierarchical user permissions (ACLs, inherited groups, org trees, document-level security)**, the best choice depends on whether you want the vector database to **own authorization semantics** or simply provide **fast filtered retrieval**. Most production systems still keep authorization logic in a…
For complex, hierarchical user permissions (ACLs, inherited groups, org trees, document-level security), the best choice depends on whether you want the vector database to own authorization semantics or simply provide fast filtered retrieval. Most production systems still keep authorization logic in a dedicated policy layer and use the vector DB for early, secure filtering.
My ranking:
| Database | ACL / permission fit | Best for |
|---|---|---|
| Weaviate | ⭐⭐⭐⭐⭐ | Enterprise semantic search with complex filters + hybrid retrieval |
| Qdrant | ⭐⭐⭐⭐½ | Custom ACL models with rich metadata payloads |
| PostgreSQL + pgvector | ⭐⭐⭐⭐½ | Permission-heavy apps already built around SQL/RBAC |
| Pinecone | ⭐⭐⭐⭐ | Managed simplicity with application-managed ACLs |
| Milvus | ⭐⭐⭐⭐ | Very large-scale vector infrastructure |
Anjali Rajawat Aaron's Generative AI Feeds## Best overall: Weaviate
For a system like:
Company
└── Division
└── Department
└── Project
└── Document
└── ACL entries
Weaviate is usually the strongest dedicated vector database choice because it combines:
This matters because an ACL failure mode is:
vector search
↓
retrieve top 100 documents
↓
remove unauthorized docs
You may have already lost recall because the authorized documents were never in the candidate set.
The safer pattern is:
user identity
↓
authorization service
↓
effective permissions
↓
vector query filter
↓
semantic retrieval
Anjali Rajawat Best AI WebA typical document payload might look like:
{
"tenant_id": "acme",
"department": "finance",
"classification": 3,
"allowed_groups": [
"finance",
"executives"
],
"project_ids": [
"project_123"
]
}
Then your authorization service expands:
User:
alice
Groups:
finance
finance-managers
Projects:
project_123
into a filter:
allowed_groups contains finance
OR
allowed_groups contains finance-managers
AND
project_ids contains project_123
If your ACL model is highly custom, Qdrant is very attractive.
Examples:
allowed_user_ids[]Qdrant's payload filtering model is excellent for this style because metadata is a first-class part of the search model.
I would choose Qdrant over Weaviate when:
If your permissions already live in relational tables:
users
groups
group_memberships
documents
document_permissions
embeddings
Postgres can be the cleanest architecture.
You can express:
much more naturally than a vector database.
Example:
Find semantically similar documents
WHERE
user belongs to allowed group
AND document classification <= clearance level
For organizations with existing IAM systems, this can beat a dedicated vector database.
I would not model a deep hierarchy entirely inside vector metadata:
document:
{
allowed_users:
[
"bob",
"alice",
"carol",
...
]
}
At enterprise scale this becomes difficult because:
A better approach:
For an enterprise semantic search product:
For a SharePoint/Google Drive–style permission model with nested groups and inherited access, I would start with Weaviate + a dedicated authorization service or Postgres/pgvector if your IAM model is already SQL-centric.
I would not model a deep hierarchy entirely inside vector metadata:
document:
{
allowed_users:
[
"bob",
"alice",
"carol",
...
]
}
At enterprise scale this becomes difficult because:
A better approach:
For an enterprise semantic search product: