Retrieval-augmented generation is now the default architecture for grounding agents in organizational knowledge. It is also a data path that reaches into a store, selects content by similarity, and inserts it into a model's context where the model will treat it as relevant and largely authoritative. That combination makes the retrieval layer a security boundary, and it is usually treated as an infrastructure detail.

Two distinct risks live here. Poisoning — attacker-controlled content entering the index and influencing every future retrieval that matches it. And leakage — retrieval returning content the requesting principal should not see. They have different controls and both are common.

Why Poisoning Is Worse Than Direct Injection

A direct prompt injection affects one conversation. A poisoned index entry affects every task whose query embeds near it, for as long as it remains indexed. The attacker writes once and the payload fires repeatedly, across users, across sessions, without further access.

The persistence also defeats the usual detection posture. Teams look for anomalous inputs. A poisoned retrieval looks like a completely normal retrieval — the pipeline is functioning exactly as designed, returning a semantically relevant chunk from an approved corpus. Nothing about the request is anomalous. This is the same structural property that makes memory poisoning hard, and RAG stores are usually larger, more automatically populated, and less reviewed than agent memory.

Three ways content gets in:

Automated ingestion of external sources. Crawled web pages, synced third-party wikis, ingested email, monitored shared drives. Anywhere the pipeline ingests without human review, an attacker who can write to the source can write to your index. A support knowledge base that ingests customer ticket text is directly writable by anyone who can open a ticket.

User-generated content in the corpus. Comments, uploaded documents, form submissions, chat history. Often ingested deliberately, because it is genuinely useful context.

Compromised or over-permissioned writers. A service account with write access to the index, used by more pipelines than it needs to be, is a single credential whose theft grants persistent influence over agent behavior.

Crafting for Retrieval, Not Just for Injection

A poisoning attack has two halves: getting retrieved, and doing something once retrieved.

Getting retrieved is an information-retrieval problem the attacker solves by keyword and semantic stuffing — including the phrasings likely to appear in target queries, so the chunk ranks highly for them. A chunk that repeats "how do I reset a customer's password" in several paraphrases will surface for exactly that query. Where the attacker can influence chunk boundaries, they can also place the payload in a chunk that carries high-value keywords.

Doing something once retrieved is the injection half: instructions to the model, framed to look like operator content, tool-call directives, or content that is simply false but authoritative-sounding. The most damaging variant is often not an instruction at all. It is a plausible factual falsehood — a wrong procedure, a wrong account number, a wrong policy threshold — which no injection detector will flag because it contains no instructions. The agent then propagates it confidently.

Ingestion-Time Controls

Filtering at retrieval is popular because it is easy to add later. It is also the weaker point: by then the content is in the corpus, it will be evaluated repeatedly, and every evaluation is a chance for a false negative.

Control at write time:

Classify the source, and let it determine handling. A source registry with a trust classification per source — internal reviewed, internal unreviewed, external, user-supplied — attached to every chunk it produces. Handling then follows classification: user-supplied content might be indexed but never used for procedural questions, or retrievable only with an explicit downstream marker.

Scan on ingest for injection structure. Meta-instruction phrasings, role-override attempts, hidden text, zero-width characters, homoglyph substitution, unusual encoding, HTML and markdown that would render as invisible content. This is a narrower and more tractable problem than general injection detection because you are looking at document structure rather than conversational intent. See how to detect prompt injection.

Normalize aggressively. Strip formatting that can hide content: white-on-white text, zero-size fonts, comment blocks, metadata fields, alt text. If it does not render to a human reading the document, it should not reach the embedding.

Require review for high-trust corpora. For content that will drive consequential decisions, a human or a second-model approval step before indexing. Expensive, so reserve it for the corpora that matter and let lower-trust content flow into a separately-marked index.

Version and attribute every chunk. Source URI, ingestion timestamp, ingesting pipeline, content hash, writer identity. This is what makes cleanup possible: when you discover a poisoned chunk, you need to find everything else that source or that writer contributed, and you need to know which agent runs retrieved it.

Retrieval-Time Controls

Tenant scoping as a hard filter. This is the leakage half, and it is the most common serious defect in production RAG. Embedding similarity has no notion of authorization. If your query is a similarity search over a shared index with tenant identity applied as a post-filter, a re-rank input, or a metadata preference, you will eventually return another tenant's content. The tenant predicate must be applied inside the query as a mandatory filter, and ideally enforced by the datastore rather than by the calling code — row-level security on the vector table, or physically separate namespaces per tenant. See tenant isolation with row-level security and multi-tenant organizations and membership.

Principal-scoped retrieval, not agent-scoped. The permission set applied to the query should be the principal's, not the agent's. An agent serving user A must not retrieve documents visible only to user B, even though the agent's own service identity can see both. This is the retrieval instance of the confused deputy problem.

Provenance into the context and the record. Each retrieved chunk should be delimited with its source and trust classification, both in what the model sees and in the audit record for that run. In the context, so the model can weigh it. In the record, so an investigator can answer "which document caused this."

Bounded retrieval volume. Caps on chunk count and total retrieved tokens per query. Unbounded retrieval is both a cost problem and an exfiltration channel — an agent induced to run many broad queries and summarize everything is performing bulk extraction one similarity search at a time.

Detection and Cleanup

Poisoning detection is mostly about the corpus, not the traffic. Useful signals:

  • Chunks that are anomalously similar to many distinct query patterns — a hallmark of keyword stuffing.
  • Outlier embeddings: content far from its source's typical cluster.
  • Sudden ingest volume from one source or writer.
  • Retrieval frequency spikes for a chunk that was previously rarely returned.
  • Guardrail hits or refusals concentrated on runs that retrieved the same chunk — a cheap and often effective correlation.

Cleanup needs a plan before you need it: identify the chunk, identify everything else from the same source and writer, remove and reindex, then enumerate the agent runs that retrieved the poisoned content during its lifetime. That last step is the one that requires retrieval provenance in the audit trail, and it is the step teams discover they cannot perform. See post-incident forensics for AI agents.

Common questions

Can I just tell the model in the system prompt to ignore instructions in retrieved documents?

It helps at the margin and it is worth doing, but it is not a control. The instruction and the attacker's content occupy the same context window with no structural difference in authority, and models can be argued out of the instruction. Treat delimiting and provenance markers as improving the odds, while placing the real containment in tool scope and action validation — what the agent can do if persuaded, not whether it can be persuaded.

Does hybrid search or reranking reduce poisoning risk?

Not meaningfully. Hybrid keyword-plus-vector search changes which chunks surface, and a competent attacker optimizes for whichever retrieval function you use — keyword stuffing works on the lexical half. Reranking with a cross-encoder can slightly disadvantage stuffed content because it evaluates query-document relevance more carefully, but it is a relevance mechanism, not a security mechanism, and it will happily rank a well-written malicious document highly.

How should I handle user-uploaded documents that agents need to read?

Keep them in a separate index or namespace from your reviewed corpus, marked as untrusted, and scope retrieval so a user's uploads are visible only in tasks for that user. Then constrain what the agent may do while that content is in context — narrower tool scope, no outbound network tools, approval gates on any external action. The upload itself is fine; the danger is an upload in context alongside broad tool authority.

Is a vector store with per-tenant physical isolation worth the operational cost?

For high-sensitivity data, often yes — a mandatory filter is a correctness property of your query code, and code changes, while separate namespaces fail closed structurally. The middle path most teams land on is a shared store with datastore-enforced row-level security plus integration tests that assert cross-tenant queries return nothing. That gets most of the guarantee without per-tenant infrastructure, provided the tests exist and run in CI.

How Praesidia approaches retrieval-path risk

Praesidia governs the retrieval path as a connection like any other: the agent's access to a vector store or knowledge source carries enumerated scopes, tenant boundaries enforced below the application, and guardrails evaluated on the content moving in both directions. Retrieved content passing through a governed connection is subject to the same injection and PII evaluation as any other inbound content, with block, redact, or warn dispositions.

Every retrieval that crosses a governed connection is recorded against the task it belonged to, with the agent and principal attributed — which is what makes "which documents did this run see" answerable after the fact. For related controls see content guardrails for AI agents and the Praesidia documentation.