LlamaIndex Security Patterns: Trust Boundaries in a RAG Pipeline
A LlamaIndex application ingests documents, retrieves chunks, and synthesizes an answer, and each stage is a trust boundary. This article walks the security patterns that matter: enforce per-user document access at retrieval, treat ingested content as untrusted, scope query-engine tools, and govern the model call and its response. It marks which controls live in your ingestion code and which need an enforcement layer on the HTTP path to the model.

A LlamaIndex query runs a pipeline: documents are ingested and embedded into an index, a retriever pulls the chunks most similar to the query, and a response synthesizer feeds those chunks plus the question to a model. Three stages, three trust boundaries. The index holds content from sources you may not fully control, the retriever decides which chunks a given user gets to see, and the synthesizer sends retrieved content to the model as context the model treats as authoritative. LlamaIndex gives you the pipeline; the boundaries are yours to enforce. I want to walk the patterns that hold under a real access model and a real adversary, and mark which live in ingestion code and which need a control on the request path. This sits alongside AI security for RAG systems and RAG poisoning prevention.
Enforce per-user access at retrieval, not after
The most common LlamaIndex security failure is a shared index with no per-user filtering. Every user's query retrieves from the whole corpus, so a chunk from a document one user should never see can surface in another user's answer. Embedding similarity has no concept of authorization, so the retriever will happily return a restricted chunk if it is the closest match. The pattern is metadata filtering bound to the caller's entitlements, applied at query time:
Store the access metadata at ingestion, and filter on it at retrieval using the caller identity supplied per request. Filtering after the model has already seen the chunks is too late, because the content is already in the context window. Access control on vector store retrieval is the load-bearing control in any multi-tenant RAG app.
Treat ingested content as untrusted input
Anything that lands in the index can end up in a prompt. If your ingestion pipeline pulls from web pages, shared drives, email, or user uploads, it is pulling untrusted content that can carry indirect prompt injection, an instruction planted in a document that the model reads as a command when the chunk is retrieved. LlamaIndex's document and node ingestion does not sanitize for this. The pattern is to treat ingestion as a trust boundary: record the provenance of every source, isolate untrusted sources from trusted ones in the index metadata, and never grant retrieved content the authority of a system instruction. Retrieved chunks are data, and data does not get to issue commands.
Scope query-engine tools the way you scope any tool
LlamaIndex query engines are frequently wrapped as tools and handed to an agent, and a QueryEngineTool that reaches a database or an API is exactly as powerful as the credential behind it. The pattern matches any agent-tool boundary: least-privilege credentials, argument constraints, and per-caller authorization on each invocation. A query engine over a sensitive index gets a retriever already scoped to the caller, so even a tool the agent decides to call cannot pull content the caller has no right to.
Govern the model call and the synthesized response
The synthesizer sends retrieved context and the user question to the model over HTTP, and the model returns an answer that may quote the retrieved content verbatim. Two controls belong on that exchange. The outbound call carries the assembled prompt, retrieved chunks and all, which is where prompt-content classification applies before the data leaves your boundary for the provider. The inbound response can carry regulated data lifted straight from a retrieved document, which is where response inspection applies before the answer reaches the user. Both sit on the decrypted HTTP path between your application and the model, and the timing is unforgiving: Google Mandiant's M-Trends 2026 report put median attacker handoff at 22 seconds, so a control that inspects this traffic after the fact provides a record and no prevention.
Where the patterns split
The ingestion-side patterns live in your code. What you index, what provenance you record, how you tag access metadata, and what credential a query-engine tool holds are pipeline architecture, and no network layer supplies them. The request-side patterns live on the HTTP path: classifying the assembled prompt before it reaches the model, authorizing the call against the caller identity, and inspecting the response before it returns. That second set is where an external enforcement layer applies, because it governs the traffic the pipeline emits rather than the indexing that happens inside your process. A poisoned chunk written into your vector store is an ingestion problem you fix at the source; a poisoned chunk riding an outbound prompt is traffic a control on the path can see.
DeepInspect
LlamaIndex builds the retrieval pipeline. DeepInspect governs the model traffic that pipeline generates.
DeepInspect is a stateless proxy on the AI request path between your LlamaIndex application and the model endpoints it calls. It binds each call to the caller identity your application supplies, classifies the assembled prompt, retrieved context included, across PII, PHI, source code, and jurisdictional categories, and inspects the synthesized response before it returns to the user, applying a deterministic pass, block, or modify decision inline and fail-closed. It commits a per-decision audit record for every call. The retrieval access model and the ingestion trust boundary stay your job, enforced in the pipeline where the index lives. DeepInspect adds the payload governance and audit on the HTTP path that a retrieval framework running inside your process cannot provide. Book a demo today.
Frequently asked questions
- How do I stop one user from seeing another user's documents in RAG?
Filter retrieval by the caller's entitlements at query time, not after. Store access metadata such as a tenant or owner ID on every node at ingestion, and construct the retriever with metadata filters bound to what this specific user may see, using identity supplied per request. Embedding similarity has no notion of authorization, so an unfiltered retriever will return a restricted chunk whenever it is the closest match to the query. Applying the filter at retrieval keeps forbidden content out of the context window entirely, which is the only point where exclusion still works.
- Is ingested content a security risk in LlamaIndex?
Yes, whenever it comes from sources you do not fully control. Web pages, shared drives, uploads, and email can carry indirect prompt injection: an instruction embedded in a document that the model reads as a command once the chunk is retrieved and placed in context. LlamaIndex ingestion does not sanitize for this. Treat ingestion as a trust boundary by recording provenance, separating untrusted from trusted sources in metadata, and never granting retrieved content the authority of a system instruction. Retrieved chunks are data to be reasoned over, not commands to be followed.
- Do I need a gateway if my vector store already has access control?
They cover different boundaries. Vector store access control decides which chunks a user's query may retrieve, which is essential and lives in your pipeline. A gateway on the HTTP path governs the traffic to the model: it classifies the assembled prompt before retrieved content leaves your boundary, authorizes the call against the caller, and inspects the response before it reaches the user. Retrieval filtering keeps forbidden content out of the prompt; the gateway governs what happens to the content that legitimately enters the prompt and comes back in the answer. Both belong in a defensible RAG deployment.
- Where does response inspection fit in a RAG pipeline?
On the inbound leg from the model, before the synthesized answer reaches the user. A response can quote regulated data lifted directly from a retrieved document, so even a correctly scoped retrieval can produce an answer that should be redacted or blocked for this caller. Inspecting the response on the decrypted HTTP path lets a control apply policy to what the model actually returned, independent of what the retriever pulled. It is the last checkpoint before the content leaves your boundary, and it catches cases where the risk is in the synthesis rather than the retrieval.