Vector databases need the geometry of your embeddings to search them, so the vectors usually sit in the database exactly as the embedding model produced them, next to the documents' metadata. Anyone who gets a snapshot, a backup or an over-privileged database account gets both.

hadamask protects that data before it leaves your application.

  • Embeddings go through a secret orthogonal transform. Queries get the same transform, so the database computes exactly the same cosine, dot-product and L2 scores as on the clear vectors. Index, database and recall stay the same.
  • Metadata and document text are encrypted field by field with AES-256-GCM, with a fresh nonce per value and length padding.
  • Filters still work. Fields declared blind get keyed equality tokens; fields declared plaintext stay in clear and support ranges.
  • Keys stay with you. It is a library, not a proxy or a service. The master key can stay wrapped by HashiCorp Vault, AWS KMS, Google Cloud KMS or Azure Key Vault.

The longer story, including what it leaks, is in the write-up.

What it is not

The embedding transform is obfuscation with measured leakage, not encryption. It hides the coordinate system, but the relative geometry of the corpus, which documents are similar to which, stays visible. In the paper's experiments, an attacker holding only the protected vectors and public data from the same distribution reached median accuracies of 81 to 87% on four-way topic inference. Metadata is encrypted. hadamask is alpha software and has not had an external cryptographic audit.

What is storedProtectionWhat a snapshot still reveals
Encrypted fields (the default)AES-256-GCM, fresh nonce per value, field name and key id as associated dataThat the field exists, and a size class for long values
Blind fieldsEncrypted, plus an HMAC-SHA256 equality tokenWhich records share a value, and how often
Plaintext fieldsNone, by your choiceEverything
EmbeddingsKeyed orthogonal transformAll pairwise similarities: clusters, duplicates, neighbourhoods. Not the coordinates

Install

pip install "hadamask[pgvector]"          # or qdrant, weaviate, milvus, chroma, ...
pip install "hadamask[all]"               # every database, framework and key manager
from hadamask import MasterKey, MetadataPolicy, Protector
from hadamask.adapters.qdrant import QdrantStore

protector = Protector(MasterKey.generate("demo1"), MetadataPolicy(plaintext=["year"], blind=["client"]))
store = QdrantStore(client, protector)
store.create_collection("docs", dim=1536, metric="cosine")
store.upsert("docs", ids, embeddings, payloads)
hits = store.search("docs", query_embedding, k=5, where={"client": "ACME"})

Where it runs

Qdrant, Weaviate, Milvus, Chroma, pgvector, Elasticsearch, OpenSearch, Redis Stack and MongoDB Atlas Vector Search, behind one API, plus LangChain and LlamaIndex wrappers for any vector store those frameworks support. Every adapter passes the same contract test against a real server, including a check that only ciphertext reaches the database.

Paper

The method and its leakage are analysed in What a Secret Rotation Buys: Exact Retrieval and Measured Leakage in Vector Databases, Ionuț Cernica and Nirvana Popescu, Applied Sciences 16(20), 10259, 2026.

Security issues: please email [email protected] rather than opening a public issue.