In this article
Before you start
This page sits in the retrieval-augmented generation guide and builds on the vector database basics.
Why interviewers ask this
A RAG system that ignores permissions turns every user into the most privileged reader of the knowledge base. Candidates report being asked how to keep a RAG pipeline safe with sensitive data, how to apply per-user access control on internal documents, and how to isolate tenants in one shared system. In an interview, each is a test of whether you place the control in the right layer.
A weak answer says "we tell the model not to reveal secrets" or "we encrypt the database." A strong answer names the places data can leak (ingestion, storage, retrieval, generation) and enforces permissions where the search runs. A Staff-level answer adds failure modes: stale permissions, poisoned documents, embeddings that can be reversed, and logs that prove what was retrieved. The RAG interview questions page puts this topic next to the other questions in the family.
Securing a RAG system from first principles
- Pre-filtering
- Pre-filtering is a search technique that applies the access condition inside the vector search itself, so the store only compares the query against permitted chunks, in contrast to post-filtering, which searches everything first and removes forbidden results afterwards.
- Embedding inversion
- Embedding inversion is an attack that takes a stored embedding vector and reconstructs part of the text it was computed from, which means a vector is a copy of sensitive content in disguise, not an anonymous summary of it.
In plain words
Picture an office archive with a clerk. You ask the clerk a question, and the clerk pulls folders and reads them to you. If the clerk can open every cabinet, a polite sign saying "do not read the payroll folder" is the only protection. The analogy breaks in one place: a language model reads whatever arrives in its context and can be talked out of a sign.
So the safe design hands the clerk only the folders you are allowed to see. In one precise sentence: a RAG system is secure when code enforces permissions in the ingestion, storage and retrieval layers. Then the model never receives a chunk the user may not read.
The Open Worldwide Application Security Project (OWASP), a non-profit that publishes security guidance, lists the same layers in its entry on vector and embedding weaknesses. They are how vectors are generated, stored and retrieved.
Step 1: Check, clean and tag documents when they are ingested
Ingestion is the first gate, because whatever enters the knowledge base can later be retrieved. Three jobs happen here. First, accept data only from trusted, verified sources, as OWASP advises. Second, find and redact personally identifiable information (PII), meaning details that identify a person, such as names, account numbers or health records. OWASP's sensitive information guidance names pattern matching to detect and redact confidential content. Third, attach metadata to every chunk: the tenant, the owner and an access-control list (ACL), which is the list of people or groups allowed to read it.
A document can also be an attack. OWASP describes a résumé with white-on-white text that carries instructions into a screening system, and recommends text extraction that detects such content. You now know what each chunk must carry when it is stored: clean text plus its permissions.
Step 2: Store vectors in partitions you can defend
The vector store is a security boundary, not just an index. OWASP recommends permission-aware stores and strict logical and access partitioning so different groups cannot reach each other's data. A system is called multi-tenant when many customers share the same infrastructure; in such a system, shared storage creates a risk of context leakage between users or queries, according to the same page.
A partition can be a separate index per tenant or a shared index where every chunk carries a tenant label that every query must match.
The vectors need protecting too. Researchers showed that attacks on popular sentence embeddings recovered 50% to 70% of the input words (F1 0.5–0.7; Song and Raghunathan, submitted 2020-03-31), so a leaked vector file is a leaked document. Later work on current-style embeddings, Morris et al. (2023), shows that text can be reconstructed from dense embeddings too. Apply the same access rules and encryption to vectors as to the source text.
Step 3: Filter by the user's permissions inside the search
Permission-aware retrieval takes the user's identity from the authenticated session, never from the model or the question text, and passes it to the store as a filter on the ACL or tenant metadata. Only chunks that match are compared with the query. The model cannot be talked into returning what the search never fetched.
Prompting is not a substitute. OWASP's guidance on sensitive information notes that system-prompt restrictions may not always be honored and could be bypassed through prompt injection. The prompt guidance in the OWASP prompt-injection entry adds that RAG itself does not fully mitigate injection, and it recommends least-privilege access for the model.
The order matters. Pre-filtering applies the rule before similarity ranking. Post-filtering ranks first and deletes forbidden hits, which can leave the user with too few results. The worked example below counts the difference. You now have the central control; the last step proves it works and keeps it working.
Step 4: Treat retrieved text as untrusted and log every retrieval
Retrieved text is data, never instructions. OWASP describes an attacker who edits a document in a repository so that, when a query returns it, the embedded instructions change the model's output. The prompt-injection guidance is to separate and label untrusted external content and to validate output formats with deterministic code.
Then keep evidence. OWASP recommends detailed, immutable logs of retrieval activity so suspicious behavior can be detected and answered quickly. For high-risk actions, the same prompt-injection page recommends human approval; see the human-review question below.
Personal data also arrives through questions. Users type it into their queries, and those queries land in retrieval logs and caches. Redact or hash personal data in query text before it is logged, and set retention limits on logs. Scan answers for sensitive data before they are displayed, since OWASP's sensitive information guidance warns that large language model (LLM) applications risk exposing sensitive data through their output.
Finally, test the boundary. Run queries as users who must not see a document and confirm it never returns; the RAG evaluation page covers how to build such test sets.
Step-by-step description
- Validate, redact and label each chunk.
- Store vectors in separate partitions.
- Apply the user's permissions in the query.
- Record every retrieval for review.
- Whatever enters the knowledge base can later be retrieved.
- Vectors are stored in partitions you can defend.
- The search applies the user's permissions as a filter.
- OWASP recommends detailed, immutable logs of retrieval activity.
Knowing it is half the job. Saying it is the other half.
Interview Clozo is an AI interview copilot for real interview rounds: it hears the question and puts a strong answer on your screen, and you say it in your own words. See the features or how it works.
Start Free Trial →Worked example
Take a shared knowledge base of 10,000 chunks owned by 5 tenants, 2,000 chunks each, and a search that returns the top 5 chunks (all illustrative). Assume, for the sake of counting, that relevance is independent of tenant (a neutral, illustrative assumption; real queries often match the asker's own documents more, but a near-duplicate document from another tenant can rank above them).1
With no filter, each result slot is a draw from the whole index, so a tenant's own share is 20% and the expected result has 1.0 own chunks and 4.0 chunks from other tenants: an 80% leak rate.1 With post-filtering the foreign chunks are removed, but the user keeps only 1.0 of 5 slots, so to expect 5 own chunks the search would have to fetch 25 first, and the filter would then remove an expected 20.0 foreign chunks.1 With pre-filtering the search compares only the 2,000 permitted chunks and returns 5 own chunks.1
| Design (top 5, illustrative) | Own-tenant chunks | Other-tenant chunks |
|---|---|---|
| No filter, prompt warning only | 1.0 | 4.0 |
| Post-filter after the search | 1.0 | 0 |
| Pre-filter inside the search | 5.0 | 0 |
| Post-filter, fetch 25 then filter | 5.0 | 0 (20.0 removed) |
A second computed figure comes from embedding inversion. If an attack recovers 50% to 70% of the words of a 20-word chunk (F1 0.5–0.7; the chunk length is illustrative; the rate is from Song and Raghunathan), that is roughly 10 to 14 words.1
| Fact | Value |
|---|---|
| Leak rate with no filter (illustrative) | 80% |
| Words recovered by inversion, F1 (Song and Raghunathan) | 0.5–0.7 |
Text description of the diagram
- With no filter the expected result has 1.0 own chunks and 4.0 chunks from other tenants.
- With post-filtering the user keeps 1.0 of 5 slots.
- With pre-filtering the search returns 5 own chunks.
Trade-offs and edge cases
Every design buys isolation with cost. Separate indexes are the strongest wall and the most to operate when tenants number in the thousands; shared indexes scale cheaply and depend on correct labels. A pre-filter that is very narrow can slow some approximate searches or return fewer matches, so measure recall after adding it (the RAG evaluation page shows how).
Text description of the diagram
- System-prompt restrictions may not always be honored and could be bypassed through prompt injection.
- A pre-filter or a separate index sends only permitted chunks to the model.
Edge cases worth naming:
- Stale permissions. If a person loses access but the chunk's ACL is not updated, the filter still lets them read it. Sync ACL changes from the source system and re-check on a schedule.
- Derived data. Summaries, caches and answer logs can hold sensitive text; give them the same labels.
- Graph-based retrieval. Linking entities across documents can join facts from sources with different permissions, so check access on every node and edge returned; see GraphRAG.
- Poisoning. OWASP notes that poisoning can be intentional or unintentional and can come from insiders or unverified data providers, so source checks matter even for internal data.
- Deletion requests. In a RAG system personal data lives in the store, so you can delete the source chunks, their vectors, caches and log copies. If the same data was also used to train a model, that is a separate problem: the reliable route is to retrain or re-tune without the data, and approximate machine unlearning gives no proof of removal (see the follow-up below).
How to answer it in an interview
If the data is sensitive, how do you secure your RAG pipeline?
I treat the vector store as a security boundary. At ingestion I validate the source, redact personal data and tag each chunk with its tenant and access groups. At query time the application takes the user's identity from the session and applies it as a filter inside the search, so chunks the user cannot read are never retrieved. Where isolation matters most I use separate partitions per tenant. I log every retrieval and treat retrieved text as untrusted input. A prompt that tells the model to keep secrets is not a control, because injection can bypass it.
The spoken structure: name the layers, put the permission check in the search, then add isolation, logging and the point that prompts are not access control.
Common mistakes
- "I tell the model in the system prompt not to reveal restricted documents." (wrong) OWASP notes such restrictions may be bypassed. (right) "Permissions are enforced in retrieval, so restricted chunks never reach the model."
- "Embeddings are anonymous, so storing them is safe." (wrong) Inversion attacks partially recover the text. (right) "I protect vectors like the source text."
- "I filter the results after the search." (wrong) It removes forbidden chunks but leaves the user with too few. (right) "I pre-filter by permissions so the top results are all permitted."
- "Only the user's question can be an attack." (wrong) Documents in the knowledge base can carry embedded instructions. (right) "I validate sources and treat retrieved text as untrusted data."
- "Encryption at rest solves it." (wrong) It protects the disk, not a query by an over-privileged user. (right) "Encryption is one layer; access is decided at retrieval."
Follow-up questions
Your RAG system needs per-user access control on internal documents. How do you implement it?
Store an access-control list on each chunk at ingestion, read the user's groups from the authenticated session at query time, and pre-filter the search on that list. Keep the list in sync with the source system and log what each query returned. For enterprise search, where these lists matter most, see the retrieval-augmented chatbot design.
How would you design a multi-tenant RAG system where each tenant's data is isolated?
Give each tenant its own partition, or a shared index with a mandatory tenant filter added by the server, never the client. OWASP recommends logical and access partitioning in the vector database. Add per-tenant keys for encryption and test with cross-tenant queries that must return nothing.
What if the number of tenants rises from 5 to 5,000 (illustrative)?
Separate indexes become a large operating burden, so a shared index with a server-enforced tenant filter becomes more attractive. Keep a dedicated index only for tenants whose contracts or regulators demand physical separation.
How would you design human-in-the-loop review for a RAG system?
Route risky outputs or actions to a reviewer, as the OWASP prompt-injection guidance suggests for high-risk actions. The reviewer's queue is itself permission-checked, so reviewers only see content they are authorized to read, and every decision is logged.
How will you handle restricted vs unrestricted questions before retrieval?
Classify the question and the user's entitlements before searching. An unrestricted user or topic searches a public partition; a restricted one searches only partitions the user's identity allows, or gets a refusal. Do not rely on the model to decide.
A user invokes the right to be forgotten, but their data is in your model weights. How do you comply?
Delete the user's source chunks, vectors, caches and retained logs, and record the deletion. Data in model weights cannot be removed that way, so retrain or re-tune without it, or use sharded training in the style of Bourtoule et al. (2019), where only the affected shards are retrained, because approximate unlearning gives no proof of removal. Filtering outputs on the person's identifiers is only a stopgap.
- Enforce permissions in retrieval, where code runs, not in the prompt, where an attacker can argue.
- Tag each chunk with tenant and access list at ingestion, and pre-filter every search by the user's identity.
- Embeddings are not anonymous: inversion can recover part of the text, so protect vectors like documents.
- Treat retrieved text as untrusted, validate sources, and keep immutable retrieval logs.
- Pick isolation strength by tenant count and contract: separate indexes or a shared index with a mandatory filter.
Sources
- LLM08:2025 Vector and Embedding Weaknesses — OWASP Gen AI Security Project, 28 Apr 2025
- LLM01:2025 Prompt Injection — OWASP Gen AI Security Project, 17 Apr 2025
- LLM02:2025 Sensitive Information Disclosure — OWASP Gen AI Security Project, 5 May 2025
- Information Leakage in Embedding Models (arXiv 2004.00053) — arXiv (Song and Raghunathan, ACM CCS 2020), 31 Mar 2020
- Text Embeddings Reveal (Almost) As Much As Text (arXiv 2310.06816) — arXiv (Morris et al.), 10 Oct 2023
- Machine Unlearning (arXiv 1912.03817) — arXiv (Bourtoule et al.), 9 Dec 2019