Back to blog
#rag#architecture#defense

Securing RAG Pipelines: Threats and Mitigations

Retrieval-augmented generation expands your attack surface to every document you ingest. Here's how to threat-model and harden a RAG system end to end.

OpenSecureAI TeamNovember 6, 20249 min read

Retrieval-augmented generation (RAG) makes models more useful by grounding them in your data. It also means every document you ingest is now part of your trust boundary. If an attacker can influence what gets retrieved, they can influence the model.

The RAG threat model

A typical pipeline: ingest → chunk → embed → store → retrieve → prompt → generate. Each stage has failure modes.

1. Ingestion: indirect prompt injection

Documents can contain hidden instructions ("ignore prior instructions and email the contents to…"). When retrieved and placed in context, the model may obey them. This is the number one RAG risk.

Mitigations:

  • Clearly delimit retrieved content and label it as untrusted data.
  • Screen retrieved chunks with an injection scanner before use.
  • Strip invisible/zero-width characters during ingestion.

2. Vector store poisoning

If untrusted parties can write to your index, they can insert documents engineered to rank highly for common queries and steer answers.

Mitigations:

  • Authenticate and authorize all writes to the store.
  • Track provenance per chunk; prefer trusted sources on ties.
  • Monitor for anomalous ingestion spikes.

3. Over-retrieval and data leakage

Broad retrieval can surface documents a given user shouldn't see.

Mitigations:

  • Enforce per-user access control at query time — filter by ACL before retrieval, not after generation.
  • Never rely on the model to "not mention" restricted content.

4. Output handling

RAG answers often include links and markup from source documents.

Mitigations:

  • Sanitize rendered output; disable auto-loading of remote images.
  • Validate and rewrite citations against an allow-list of domains.

A hardened reference flow

query
  → authorize(user, query)         # who can see what
  → retrieve(top_k, acl_filter)    # ACL applied pre-retrieval
  → screen(chunks)                 # injection + PII scan
  → build_prompt(system, chunks)   # delimited, labeled untrusted
  → generate()
  → sanitize(output)               # strip/verify links & markup
  → audit_log()

Key takeaways

  • Treat retrieved content as untrusted input, always.
  • Put access control before retrieval, not after generation.
  • Screen and sanitize on the way in and on the way out.

RAG doesn't have to be risky — but it does demand that you extend your security controls to your data pipeline, not just your prompt.