"We send the vectors to the model, not the raw text, so the sensitive data never leaves." I have heard some version of that in more than one architecture review, and it sounds reasonable. Your documents go into a vector database as long lists of floating-point numbers. The numbers look nothing like the source. So surely the private data is gone.

It is not gone. Embeddings are not anonymization. The vectors can be turned back into the original text, and in a standard RAG pipeline the model reads the plaintext anyway. Two separate things are wrong with the belief, and if you are putting regulated data behind a retrieval system it is worth getting both straight.

This came up as a real question when we built the invoice extraction pipeline inside our own invoice-automation platform (Python plus RAG). The documents there are invoices, so they carry financial data and personal data in the same file. Its automated vendor comparison and reconciliation replaced work the client used to do by hand, but the savings were never the interesting part in a security conversation. "Is this data actually private once it is in the vector store" was, because a client's security reviewer will ask it, and "it's just embeddings" is not an answer that survives follow-up questions.

Diagram of a RAG query: the query embedding is used only to look up the top-k original text chunks, which are injected as plaintext into the LLM prompt, with a second arrow showing an embedding being inverted back into readable text
In standard RAG the vector is an index key, not the payload. The model reads the retrieved plaintext, and the vector itself can be inverted back toward the source text.

What standard RAG actually sends to the model

Start with the dataflow, because the "send vectors instead of text" mental model is wrong before you even get to inversion.

Here is what a standard pipeline does. Documents get chunked, each chunk is embedded, and the vector is stored in the database alongside the original text of that chunk. At query time you embed the incoming query, run a similarity search, and get back the top-k most relevant original text chunks. Those text chunks are what go into the LLM prompt. Chat LLM APIs consume tokens, which is to say text, not raw vectors. The embedding is an index key used to find the right chunk. It is never the thing the model reads.

So the model sees the plaintext of whatever retrieval pulled. If a query surfaces the invoice with a customer's bank details, those details are in the prompt that goes to the provider. There is no version of standard RAG where you hand the model a vector and it reasons over the hidden data without ever seeing it. (The general shape of that pipeline, chunking, hybrid retrieval, reranking, and why it is harder than the demo, is in our RAG implementation walkthrough.) The privacy question is therefore not "do the vectors hide the data from the model." The model gets the text. The question is which text you let retrieval fetch, and who can reach the store. Hold that thought, because it is where the real answer lives.

Can you turn an embedding back into text?

Yes, well enough to plan around. This is the part most people find surprising, so here is the hard number first.

vec2text reconstructs about 92% of short texts exactly from their embeddings, and it needs only text-and-embedding pairs to train the attacker, not access to the embedding model's weights (Morris et al., "Text Embeddings Reveal (Almost) As Much As Text," EMNLP 2023, arXiv:2310.06816; independently reproduced in 2025, arXiv:2507.07700). Exactly, meaning the original string comes back, not a paraphrase. Earlier work is less dramatic but points the same way: it recovered roughly 50 to 70 percent of the input words from popular sentence embeddings, and showed the vectors also leak sensitive attributes such as authorship, and whether a given record was in the training set (Song and Raghunathan, "Information Leakage in Embedding Models," ACM CCS 2020, arXiv:2004.00053).

The practical translation is short. Anyone who can query the same embedding model can approximately invert your stored vectors. So if the index leaks through a misconfigured database, an old backup, or a shared analytics pipeline, "they are only embeddings" buys you very little. You should treat a vector store holding embeddings of sensitive text with roughly the same care you would treat a store holding the text.

Mitigations exist, and they cost you retrieval quality. Adding Gaussian noise to the embeddings, or quantizing them, reduces how cleanly they invert, but both trade off retrieval accuracy, so neither is a free default you switch on and forget (arXiv:2402.12784). They are a dial you tune against a threat model, with a measurable hit to how well search works. They are worth tuning in a specific build, once the actual privacy design is already in place.

What actually protects data, and what only feels like it does

RAG does genuinely help privacy, for different reasons than the myth claims, and only if you design for it. The structural win is data minimization: the provider sees the top-k relevant snippets for a given query, never the whole knowledge base. If prompts get logged, retained, or breached, the exposure is a handful of chunks instead of the corpus.

The rest is design you have to add. Keep the vector store and the source corpus on infrastructure you control, so only the minimal per-query context crosses your trust boundary.

Then treat retrieval as an interception point. Filter by access control so a query fetches only what this specific user is allowed to see. Redact or mask PII inside the retrieved chunks before they become prompt text, so the chunk with the bank details never reaches the model.

When the data warrants it, run a small open-weight model on-premise. The retriever supplies the facts and the model only reasons over them, so for that tier nothing leaves at all.

Defense architecture in four tiers: a user query enters, then on infrastructure you control a self-hosted index, an access-control filter, and PII redaction do their work, then only minimal redacted per-query context crosses the boundary, and at the model tier an on-prem model serves the sensitive data while a managed API handles only non-sensitive data
The controls that matter sit before the boundary. Only minimal, redacted context crosses it, and the sensitive tier runs on a model that never leaves your perimeter.

Put the myths and the real controls side by side, because the contrast is the whole point:

Feels private, but isn't

  • "We send vectors, not text" (the model reads the retrieved plaintext)
  • "Embeddings are anonymized" (they reconstruct about 92% of short texts exactly)
  • Storing PII in chunks and trusting the vector to hide it
  • A managed API purely because it is convenient

Genuinely reduces exposure

  • Data minimization: only the top-k snippets per query reach the provider
  • Self-hosted index: corpus and vectors stay on infrastructure you control
  • Access-control filtering and PII redaction applied at retrieval time
  • A local or open-weight model on-premise for the sensitive tier

One aside so nobody reaches for the wrong reason. RAG also tends to lower input-token cost, because you send a few relevant chunks per query instead of the entire corpus. That is real, but retrieval adds its own small cost, and vector search selects fewer tokens, it does not compress them. Treat cost as a side benefit. The privacy case has to stand on its own.

Questions

Frequently asked questions

Can embeddings be reversed?

Yes. A technique called vec2text reconstructs about 92% of short texts exactly from their embeddings, recovering the original string rather than a paraphrase (Morris et al., EMNLP 2023, arXiv:2310.06816, independently reproduced in 2025). The attack trains on text-and-embedding pairs alone and does not need access to the embedding model's weights, so anyone who can query the same model can approximately invert your stored vectors. Treat a vector store of sensitive text with roughly the same care you would give a store holding the text itself.

Are embeddings anonymized or PII-safe?

No. An embedding is a retrieval index, not a privacy layer, and it reconstructs about 92% of short texts exactly, so the numbers never hide the underlying data. Earlier research also showed embeddings leak sensitive attributes such as authorship and whether a given record was in the training set (Song and Raghunathan, ACM CCS 2020). If a vector holds an embedding of PII, you should treat that vector as PII.

Is a vector database secure?

A vector database is only as secure as the infrastructure and access controls you put around it. Because the stored vectors invert back toward their source text, an index that leaks through a misconfigured database, an old backup, or a shared analytics pipeline exposes roughly what the plaintext would. Keep the store and the source corpus on infrastructure you control, and filter retrieval by access control so a query fetches only what that user is allowed to see.

Is RAG safe for sensitive or regulated data?

RAG can be safe for regulated data when you design for it, but not by default. In a standard pipeline the model reads the retrieved plaintext, so your real risk is which text retrieval fetches and who can reach the store. Keep the corpus and vectors self-hosted, filter retrieval by permission, redact or mask PII inside chunks before they become prompt text, and run a small open-weight model on-premise for the most sensitive tier so nothing leaves the perimeter.

What is embedding inversion (vec2text)?

Embedding inversion is the technique of turning a stored embedding back into readable text. vec2text is the best-known method, reconstructing about 92% of short texts exactly from their embeddings and training on text-and-embedding pairs alone, without the embedding model's weights (Morris et al., EMNLP 2023, arXiv:2310.06816). Mitigations such as adding Gaussian noise or quantizing the vectors reduce how cleanly they invert, but each one trades off retrieval accuracy, so neither is a free default.

Does standard RAG send my data to the LLM?

Yes. Chat LLM APIs consume tokens, which is to say text, so a standard RAG pipeline injects the top-k retrieved plaintext chunks straight into the prompt. The embedding is only an index key used to find the right chunk, never the thing the model reads, so if a query surfaces an invoice with bank details, those details are in the prompt that goes to the provider.

Running RAG on sensitive data: what I would tell a CTO

Drop the idea that the vector database is a privacy layer. It is a retrieval index. It reads back to text, and it feeds text to the model. Decide instead on the two things that actually define your risk: what crosses your trust boundary on each query, and who can reach the index.

For most sensitive work, that is the architecture I would design:

  1. Keep the corpus and the vectors on infrastructure the client controls.
  2. Filter retrieval by permission, so a query fetches only what that user is allowed to see.
  3. Strip or mask PII before any chunk becomes prompt text.
  4. Put the most sensitive tier on a local or open-weight model, so for that data nothing leaves the perimeter at all.

You keep retrieval quality, and you get a threat model you can defend when the security reviewer starts asking real questions.

If you are weighing how to run retrieval over regulated data and want people who have shipped it on real financial documents, that is the day-to-day work of our AI and RAG development team. Design the boundary first. The vectors were never the wall you thought they were.