Skip to content

RAG and Embeddings

Build RAG Over Customer Documents Without Putting PII in the Vector Store

A retrieval pipeline touches personal data twice. Once when you embed 40,000 support articles and contracts, and again on every query, when the retrieved chunks go into the prompt. If you mask only the chat call, the embeddings provider and your vector store still hold every name and email in clear text.

Maskflare masks both. Embeddings requests through the gateway get deterministic tokens, so ada@example.com becomes the same token in every chunk and in every query, and retrieval keeps working on masked text.

Data stays in your boundary
  1. 01

    Identify sensitive values

  2. 02

    Replace with stable tokens

  3. 03

    Restore only inside your boundary

Why the usual approach falls short

Masking only the chat call leaves names and emails in the embeddings provider and the vector store. Random tokens break retrieval. Deterministic tokens keep it working.

The Maskflare approach

Point your embeddings and chat clients at the Maskflare gateway. On embeddings routes, each detected value is replaced with a deterministic token: same value, same token, within an API key. Queries are masked the same way, so they still land near the right chunks. If masking can't complete, the embeddings request fails closed instead of going out unmasked. In your own pipeline, the Python SDK's `mask(..., deterministic=True)` does the same before you write to the index. At answer time, the chat response is restored, so users read real values.

Benefits

Retrieval still works

Deterministic tokens mean a masked query matches masked chunks. A search for a customer's email finds their documents.

Fail closed

An embeddings request that can't be masked is refused, not sent in clear text. A silent leak into a permanent index is the failure you most want to avoid.

No PII in the index

The vector store, its backups, and anyone with read access see tokens, not names, emails, or account numbers.

Readable answers

Chat responses are restored, including while streaming, so the end user never sees a token.

Built on

Frequently asked questions

Why not just use random tokens?

Because the same customer would get a different token in every chunk and every query, and similarity search would stop matching them. Deterministic tokens give each value one stable stand-in within an API key.

What does fail closed mean here?

If the gateway can't finish masking an embeddings request, it rejects the request rather than forwarding the original text. Your pipeline sees an error and can retry.

Can tokens in the index be turned back into values?

Masked values resolve for 30 days. For an index that lives longer, plan for it: re-index on a schedule, or use a hash action on fields you only need to match, not read back.

Does masking hurt retrieval quality?

Semantic content stays; only the detected values are replaced. Queries that depend on the meaning of the text behave as before. Queries that depend on a specific name only match if the query contains the same value, which is then masked to the same token.

Do we have to use the gateway?

No. The Python and TypeScript SDKs can mask text inside your ingestion job before you call any embeddings provider, and unmask the final answer.

See it on your own data

Try Maskflare free.
Bring your hardest prompts.

28-day free trial or 10,000 requests, whichever comes first. Point one app at the gateway or enroll a few laptops,
and watch what gets masked. Or talk to us first.