Vector stores and embedding leaks
Embeddings look like harmless lists of numbers. Treat them, and the vector store that holds them, as carefully as the original text.
In 60 seconds
Vector stores and embedding leaks
Embeddings look like harmless lists of numbers. Treat them, and the vector store that holds them, as carefully as the original text.
What embeddings can reveal
- Similarity can be probed. Anyone who can run searches and see scores can test guesses: "Is there a document close to layoff plan for the Pune office?"
- Text can sometimes be partly recovered. Researchers have shown that, in some settings, parts of the original text can be reconstructed from embeddings. How well this works depends on the model and what the attacker can access. It is an active research area, so plan as if it is possible.
- The raw text is often right there. Many vector stores keep the original chunk text next to each vector, as metadata. Then the store holds the plain text anyway.
Controls for vector stores
| Risk | Control |
|---|---|
| Vector database reachable from the internet | Private network only; strong authentication; no default passwords; separate credentials per app |
| One tenant reads another's vectors | Per-tenant collections or namespaces, mandatory filters, separate keys where possible |
| Raw similarity search exposed to users | Do not expose the search endpoint directly; return answers, not vectors or scores; rate-limit |
| Data at rest and in transit | Encryption on disk and TLS on every connection; manage keys properly |
| Backups, exports and test copies | Same protection as production; do not copy real data to test systems casually |
| Deletion requests | Map each document to its vector ids; delete vectors, chunk text, caches; handle backups by policy |
Deletion and the right to erasure
def erase_document(doc_id: str) -> None:
vector_ids = index_map.pop(doc_id, []) # doc id -> list of vector ids
if vector_ids:
vector_db.delete(ids=vector_ids)
chunk_store.delete(doc_id) # stored chunk text
answer_cache.invalidate(source=doc_id) # cached answers that cited it
audit_log.write(event="erased", doc_id=doc_id)- Vector store on a public port with a default password
- Search API returns top 50 chunks with scores to the browser
- No link from source document to its vectors
- Old collections kept "just in case"
- Private network, authentication, separate keys
- Server calls search, returns only the answer and citations
- Every vector tagged with document id, tenant and version
- Old collections deleted after migration, on a schedule
Watch and read more
Lab
A written security review of an imaginary vector store setup, with fixes and an erasure plan.
The problem
Read this imaginary setup: "Our HR assistant stores all documents for our three client companies in one collection. The vector database runs on a cloud server with its port open to the internet so developers can reach it from home. The front end calls the search endpoint directly and shows the top 20 chunks with scores. Chunks are stored with their full text. We re-embedded everything last month with a new model; the old collection is still there. We don't track which vectors came from which file."
- List at least five problems.
- For each problem, write a fix and who should own it.
- Write the steps to erase one employee's documents completely.
- Put the fixes in order: what do you do this week, and what this quarter?
You are done when
Hard questions
Try to answer before you reveal. If you can answer these, you understood the lesson.
Q1The team says: "We removed the full text from the metadata, so the vector store no longer holds personal data." Is that right?Reveal
Not fully. The embeddings are still derived from personal data, similarity searches can still reveal what exists, and research suggests text can sometimes be partly recovered. Other metadata like names, titles or file paths may also be personal. Removing the text reduces risk, but the store still needs access control, and erasure still needs the mapping.
Q2Why is rate limiting useful for a vector search endpoint, even behind login?Reveal
Probing needs many queries: testing guesses one by one, or collecting many results to rebuild a document. A logged-in insider or a stolen account can do this. Rate limits and alerts on unusual query volume make probing slow and visible. They also help against cost abuse.
Questions people ask
Can we make embeddings safe by hashing or scrambling them?
Not in a simple way. Hashing destroys the similarity that makes search work. Some research methods try to protect embeddings while keeping search useful, but they have trade-offs. For most teams, strong access control and isolation are the practical answer.
Is embedding inversion a practical threat today?
It depends on the model, the data and the attacker's access. Research shows it can work in some settings. Since many stores also keep raw text next to the vectors, access control matters more in practice than the inversion question.
Should we self-host the vector database?
Either can be secure. Self-hosting gives control but you must patch, back up and secure it yourself. A managed service does much of that, but you must configure access, check where data is stored, and review the contract. Choose based on your team's skills and data rules.
What about personal data inside the chunks?
Ask whether it needs to be indexed at all. Removing or masking personal data before indexing reduces what can leak. For questions about legal duties, talk to your legal or privacy team.
Lesson test
5 questions. Get 3 right (60%) to pass and complete this lesson.