Integrations#

Each integration is an optional extra, so the core stays free of dependencies. The OPA, OpenFGA, SpiceDB, Cerbos and Keto authorizers need no extra at all: they use the standard library’s HTTP client.

Integration

Kind

Install

Pre-filters

PostgreSQL + pgvector

Backend

wardowl[pgvector]

Yes, inside the SQL query

Chroma

Backend

wardowl[chroma]

Yes, as a where clause

Elasticsearch

Backend

wardowl[elasticsearch]

Yes, inside the kNN search

OpenSearch

Backend

wardowl[opensearch]

Yes, inside the k-NN search

Qdrant

Backend

wardowl[qdrant]

Yes, as a query_filter

Milvus

Backend

wardowl[milvus]

Yes, inside the vector search, with parameterized filters

MongoDB Atlas Vector Search

Backend

wardowl[mongodb]

Yes, as the $vectorSearch pre-filter

Weaviate

Backend

wardowl[weaviate]

Yes, inside the vector search

Redis

Backend

wardowl[redis]

Yes, in the same KNN query

LanceDB

Backend

wardowl[lancedb]

Yes, before the vector search ranks

FAISS

Backend, in process

wardowl[faiss]

Yes, an ID selector inside the search

Vespa

Backend

wardowl[vespa]

Yes, in the YQL query, inside the nearest-neighbor search

Apache Cassandra

Backend

wardowl[cassandra]

Yes, in each ANN query’s WHERE

Pinecone

Backend

wardowl[pinecone]

Yes, as the query’s metadata filter

Open Policy Agent

Authorizer

none

When the policy returns a filter

OpenFGA

Authorizer

none

Yes, through ListObjects

SpiceDB

Authorizer

none

Yes, through LookupResources

Cerbos

Authorizer

none

Yes, from query plans

Cedar

Authorizer, in process

wardowl[cedar]

No: post-filters, every candidate decided by Cedar

Casbin

Authorizer, in process

wardowl[casbin]

No: post-filters, every candidate decided by Casbin

Ory Keto

Authorizer

none

No: post-filters, Keto has no reverse lookup

Google Drive

Permission sync onto the chunks

none (bring Google’s client)

Through MetadataACLAuthorizer

LangChain

Framework, and any LangChain vector store as a backend

wardowl[langchain]

Wrapped stores post-filter

LlamaIndex

Framework, and any LlamaIndex index as a backend

wardowl[llamaindex]

Wrapped indexes post-filter

Haystack

Framework

wardowl[haystack]

Through any wardowl backend

MCP

Agent tool server

wardowl[mcp]

Through any wardowl backend

Agent frameworks

OpenAI Agents SDK, Pydantic AI, CrewAI, AutoGen, Semantic Kernel, DSPy, through MCP

none (the framework’s MCP client)

Through any wardowl backend

HTTP service

Retrieval for any language, OIDC tokens

wardowl[server]

Through any wardowl backend

FastAPI

Reference RAG service: verified tokens, tenants, safe errors

none (your app’s FastAPI)

Through any wardowl backend

OpenTelemetry

Observer

wardowl[otel]

Choosing a store#

Every store applies the permission filter inside its own search, passes the conformance kit in CI against the real store, and keeps permission values out of query text. They differ in what is worth knowing in production:

Store

A write is searchable

Native aretrieve

Permission values travel as

Keyword search

CI tests against

PostgreSQL + pgvector

When add commits

AsyncConnectionPool

Bound SQL parameters (jsonb containment)

Full-text, mode="keyword"

PostgreSQL 17 with pgvector

Chroma

When add returns

No (a thread)

A where dictionary

No

Chroma’s in-process client

Elasticsearch

When add returns (refresh="wait_for")

AsyncElasticsearch

A terms query on type-tagged terms

BM25, mode="keyword"

9.5.5

OpenSearch

When add returns (refresh="wait_for")

AsyncOpenSearch

A terms query on type-tagged terms

BM25, mode="keyword"

3.9.0

Qdrant

When add returns (wait=True)

AsyncQdrantClient

Filter objects (MatchAny)

BM25 (IDF modifier), mode="keyword"

1.19.2

Milvus

At once (strong consistency, the default)

AsyncMilvusClient

filter_params, never in the expression

BM25, mode="keyword"

3.0.2

MongoDB Atlas Vector Search

When add returns: it waits for the search index

AsyncMongoClient

A BSON filter ($in)

BM25 (Atlas Search), mode="keyword"

Atlas Local 8.0.30

Weaviate

When add returns

WeaviateAsyncClient

Filter objects (contains_any)

BM25, mode="keyword"

1.39.12

Redis

When add returns

redis.asyncio

Hex-encoded TAG values

BM25, mode="keyword"

8.10.2

LanceDB

When add returns

No (a thread)

Hex-encoded list values (array_has_any)

BM25, mode="keyword"

LanceDB 0.40, embedded

FAISS

At once

No (a thread)

matches over the stored metadata, then an ID selector

None

faiss-cpu 1.15, in process

Vespa

When add returns

No (a thread)

Hex-encoded terms in YQL (in)

BM25, mode="keyword"

8.763.13

Apache Cassandra

When add returns, at the session’s consistency level

No (a thread)

Bound CONTAINS parameters, one ANN query per AND

No

5.0.9

Pinecone

Within seconds; at once with wait=

No (a thread)

$in on hex-encoded terms, $and, $or

No

Pinecone serverless, API 2026-07

Keyword and vector search combine into hybrid search with RankFusion, across stores as well as within one. Measured recall, latency and throughput at a million chunks are in Benchmarks for pgvector, Qdrant, Elasticsearch, OpenSearch and Weaviate.

Backends and authorizers combine freely: pgvector with OpenFGA, Chroma with OPA, a LangChain store with permissions on the chunks. A store not listed here needs only a search method; see Extending wardowl.