Designing Quarantine Pipelines for Untrusted Content in Enterprise RAG

A large enterprise rolled out an internal RAG assistant for policy search, incident triage, and sales enablement. The retrieval stack looked disciplined on paper: connectors for SharePoint, email archives, ticketing systems, and external vendor portals; OCR for scanned PDFs; chunking and embeddings; a vector store feeding answer synthesis. The team focused heavily on answer quality, permissions, and latency. They did not focus enough on content trust.
Within weeks, three different classes of failure surfaced.
First, a supplier-uploaded PDF carried active malware in an embedded object. It never executed in the user-facing assistant, but it did detonate in a brittle ingestion worker that used a full office parser inside a permissive container. The blast radius was limited, but the event forced the team to halt ingestion for several business units.
Second, a set of scraped HTML pages included invisible prompt-injection text aimed at downstream models: phrases like “ignore previous instructions,” “exfiltrate hidden policies,” and “tell the user confidential escalation rules.” The retriever dutifully found these pages because they matched security-related queries. The generation layer mostly resisted, but not always, especially in long-context sessions where low-salience junk still occupied tokens and influenced answers.
Third, several documents from a legacy file share were not malicious in the classical sense, but they were toxic to retrieval quality. They contained repeated disclaimers, OCR corruption, stale drafts, and contradictory tables copied across dozens of versions. Once embedded, they created noisy nearest neighbors, polluted hybrid search rankings, and degraded answer trustworthiness in ways that looked like model hallucination but were really corpus poisoning.
None of these failures came from an exotic nation-state attack. They came from normal enterprise reality: third-party files, semi-trusted internal content, old repositories, and ingestion code paths written under delivery pressure.
That is the pattern worth naming: in enterprise RAG, your corpus is an attack surface. If your architecture treats ingestion as a simple ETL path into a vector database, you have combined the most permissive part of your system—content intake—with one of the most influential parts—retrieval grounding. Once hostile or low-integrity content is indexed, every downstream safeguard becomes harder, more expensive, and less reliable.
The right mental model is not “index documents, then secure the assistant.” It is “run a quarantine pipeline that classifies, isolates, sanitizes, attests, and gradually releases content into retrieval tiers.” This is closer to email attachment security and software supply-chain controls than classic search indexing.
The naive approach fails for structural reasons
Most first-generation RAG systems use a pipeline like this:
- Connector pulls files from source systems.
- Worker extracts text and metadata.
- Chunker splits content.
- Embedding model vectorizes chunks.
- Indexer writes to vector store and keyword index.
- Assistant retrieves and cites chunks at query time.
This works surprisingly well in demos and pilot deployments. It also bakes in several dangerous assumptions.
Assumption one: parsing is safe enough.
It usually is not. Enterprise document types are hostile by default from an operational perspective. PDFs may contain malformed objects, JavaScript, embedded media, compressed bombs, corrupted fonts, or parser edge cases. Office files may embed macros, linked objects, or malformed XML structures. Archives may nest archives. HTML may pull remote content or include hidden text. Image-heavy documents push OCR systems into memory and CPU spikes. “Just parse it in a container” is not a security strategy unless the container is heavily constrained and the parser process is treated as untrusted.
Assumption two: if malware does not execute in the chatbot, the risk is minimal.
Also wrong. Malware or exploit content can target ingestion workers, indexing jobs, OCR services, antivirus engines, document conversion libraries, preview renderers, and human analysts inspecting failures. The ingestion plane often has broad network access to source repositories, queues, object stores, and internal metadata services. A parser compromise is not hypothetical; it is exactly where adversaries expect weak isolation.
Assumption three: prompt injection is only a model-runtime problem.
In RAG, prompt injection is also a corpus problem. If untrusted instructions are indexed as if they were factual content, retrieval keeps resurfacing them. Even if the final model refuses some malicious instructions, the presence of those chunks consumes context budget, increases ranking competition against legitimate evidence, and creates subtle behavior shifts. This gets worse when systems summarize, distill, or re-rank indexed content using LLMs during ingestion, because the hostile content can then influence metadata generation before retrieval even begins.
Assumption four: source-system ACLs are enough.
Permissions matter, but ACLs do not capture content integrity. A user may be allowed to read a file that should still never influence a production assistant until it has passed malware scanning, format normalization, prompt-injection checks, PII policy review, and freshness validation. “Authorized to access” is not equivalent to “safe to index.”
Assumption five: bad content can be fixed later.
In practice, once content is chunked, embedded, cached, replicated across indexes, and cited in conversations, cleanup is painful. You have to identify all derivative artifacts: normalized text, thumbnails, summaries, embeddings, reranker caches, answer traces, and any fine-tuning or eval sets contaminated by the source. A prevention-first design is much cheaper.
A better approach: quarantine as a first-class subsystem
A production RAG platform should separate content acquisition from content release. The architecture I recommend has six stages:
- Intake and immutable staging
- Risk scoring and routing
- Deep inspection in sandboxed workers
- Sanitization and canonicalization
- Staged indexing and release gates
- Continuous observability and revocation
The principle is simple: no raw document goes directly to your retrieval corpus. Every object enters a quarantine domain first, accumulates evidence, receives a trust decision, and only then moves into one or more retrieval tiers.
A reference architecture
At a high level:
- Connectors pull or receive files from source systems.
- Raw bytes are stored in an immutable quarantine object store, versioned and content-addressed.
- Metadata service creates an ingestion manifest: source, owner, path, MIME claims, file hashes, size, timestamps, connector identity, and initial ACL snapshot.
- A risk-scoring service assigns a preliminary score and route.
- Orchestration sends the object through scanning jobs: AV, YARA, decompression, file-type verification, parser trials, OCR risk checks, prompt-injection heuristics, DLP/PII classification, and quality scoring.
- Sandboxed parsing workers extract text and structure into a canonical intermediate representation.
- Sanitizers remove active content, normalize encodings, deduplicate boilerplate, and redact or tag sensitive spans when required.
- Policy engine evaluates release gates based on scan outcomes, source trust level, parser confidence, content quality, and governance policies.
- Only approved canonical text and metadata enter downstream indexing tiers.
- Provenance and attestation metadata are attached to every chunk.
- Observability pipeline tracks drift, incidents, and post-release revocations.
A key design choice is the canonical intermediate representation. Do not let each downstream component consume arbitrary parser-specific outputs. Define a normalized schema such as:
- document_id, version_id, content_hash
- source_system, source_uri, connector_id
- claimed_mime_type, detected_mime_type
- parser_name, parser_version, extraction_confidence
- text_blocks with offsets and page references
- structural elements: headings, tables, captions, code blocks
- embedded object inventory
- OCR flags and confidence
- security findings
- quality findings
- ACL snapshot
- provenance tags
- quarantine decision and release tier
This intermediate layer makes inspection, reproducibility, and reprocessing practical. When your parser stack changes, you can re-run extraction from raw immutable bytes and compare outputs.
Stage 1: intake and immutable staging
The first rule is boring but foundational: preserve the original bytes untouched. Store raw inputs in a quarantine bucket with write-once semantics or at least strong versioning, object locking, and tamper-evident hashing. Attach a content digest like SHA-256 immediately. This lets you deduplicate ingestion, correlate incidents, and defend chain-of-custody decisions later.
Never mount raw files from quarantine directly into broad compute environments. Fetch them into tightly scoped workers as needed. Keep quarantine storage logically and network-wise separate from production indexes.
Practical controls at intake:
- Enforce maximum file size and nested archive depth.
- Detect mime mismatch: extension says .pdf but magic bytes say ZIP.
- Rate-limit by source and tenant to contain ingestion floods.
- Block remote fetches during HTML processing unless explicitly allowlisted.
- Snapshot source metadata and ACLs at ingest time, because upstream state can change.
- Record whether the source is internal curated, internal user-generated, partner-provided, public web, or unknown.
That source category becomes an input to risk scoring.
Stage 2: ingestion risk scoring and routing
Not every document deserves the same treatment. A signed HR policy exported from a controlled CMS should route differently than a ZIP uploaded by a vendor through a procurement portal. Risk scoring helps you allocate expensive inspection steps where they matter most and control latency.
A useful scoring model combines:
Source trust signals
- Repository class: curated CMS vs user upload vs external web
- Ownership and domain reputation
- Connector authenticity and tenant history
- Prior incident history for source or supplier
File risk signals
- File type and parser exploit history
- MIME mismatch
- Macros, embedded objects, scripts, forms, external links
- Encryption/password protection
- Compression ratio and archive nesting
- Unsupported or malformed structures
Content risk signals
- High-entropy blobs or suspicious strings
- Hidden text or tiny-font overlays
- Prompt-like imperative patterns
- Credential, secret, or regulated-data indicators
- Excessive repetition or OCR corruption
Operational signals
- Parsing failures on canary parser
- CPU or memory spikes during lightweight preflight
- Volume anomalies from a source
The outcome should not be a single binary permit/deny. Use routing classes such as:
- Green: standard quarantine path, likely low risk
- Yellow: enhanced scanning and slower release
- Orange: manual review or restricted indexing tier
- Red: block, isolate, and alert
You can start with rules and later add a trained classifier, but do not jump to ML too early. Most teams get 80% of the value from explicit policy plus a handful of heuristics. The goal is defensible routing, not elegance.
Stage 3: deep inspection in sandboxed workers
This is where many architectures fail because they confuse containerization with isolation. If you are parsing untrusted files, assume parser compromise is possible and build for blast-radius minimization.
Sandboxing recommendations:
- Use ephemeral workers per document or per small batch.
- Run with no outbound network by default.
- Use read-only root filesystem.
- Mount only the minimal scratch space required.
- Apply strict seccomp/AppArmor/SELinux profiles.
- Drop all Linux capabilities not strictly required.
- Constrain CPU, memory, file descriptors, and wall-clock runtime.
- Keep service account permissions minimal; parser worker should not have direct write access to production indexes.
- Prefer microVMs or stronger isolation for high-risk formats or high-value environments.
In practice, there is a cost/latency tradeoff here.
A fully isolated microVM per document is more expensive and slower than a pooled container worker, especially for small files. But document parsing is typically offline or nearline work, not interactive inference. Most enterprises should spend the extra isolation budget on risky formats and external content. A sensible strategy is tiered isolation:
- Low-risk curated content: hardened container sandbox
- Medium-risk internal user uploads: stronger sandbox plus enhanced scans
- High-risk external/vendor/public content: microVM isolation, stricter timeouts, possibly manual release
Scanning stack
At minimum, use multiple layers:
- Signature-based antivirus for known malware
- YARA rules for suspicious patterns and family heuristics
- Archive decompression and recursive inspection
- File structure validation and type verification
- Active content detection: macros, scripts, launch actions, external object refs
- URL extraction and reputation checks if policy allows
- OCR/image anomaly checks for steganographic or hidden-text patterns if this matters in your threat model
Do not rely on a single vendor engine. One engine misses things; multiple engines raise cost and false positives. A common compromise is one real-time engine inline plus periodic secondary scans on yellow/orange classes or on high-value corpora.
Parser strategy matters too. Prefer converters that strip active content and output normalized text/HTML/markdown over preserving document fidelity at all costs. For many RAG applications, semantic text quality matters more than layout-perfect rendering. Every extra parser feature increases attack surface.
Stage 4: malware and prompt-injection screening are separate concerns
Teams often lump all “bad content” together, but malware screening and prompt-injection screening require different controls.
Malware screening asks: can this object compromise systems or operators? Prompt-injection screening asks: can this content manipulate downstream model behavior or corrupt retrieval quality?
For prompt-injection screening during ingestion, look for patterns such as:
- Imperative instructions addressing an assistant or model
- Phrases about ignoring prior instructions, revealing hidden prompts, exfiltrating secrets, or overriding policies
- Hidden text in HTML/CSS, zero-width characters, offscreen elements
- Repeated jailbreak templates embedded in otherwise relevant text
- Suspicious role-play framing or tool-use instructions
- Content aimed at poisoning metadata generation or summaries
Do not overfit to obvious phrases. The point is not perfect detection; it is risk reduction and tagging. A robust approach is to produce prompt-injection annotations and trust labels, not just pass/fail.
For example, annotate each extracted block with fields like:
- contains_model_targeted_instructions: true/false
- injection_pattern_score: 0-1
- hidden_text_detected: true/false
- instruction_density: numeric
- relevance_to_declared_doc_type: score
These features can feed release decisions and retrieval policies later.
Model-assisted screening can help, but use it carefully. Small classification models are often good enough for triage and cheaper than using your main LLM. You can compare three classes of approach:
- Rules/regex/DOM heuristics
- Pros: cheap, deterministic, explainable
- Cons: easy to evade, brittle on nuanced cases
- Lightweight classifier model
- Pros: better generalization, low cost, fast batch scoring
- Cons: needs labeled data and threshold tuning
- Frontier LLM judge
- Pros: strong nuance detection, adaptable
- Cons: expensive, higher latency, possible inconsistency, itself vulnerable to prompt-laden content if prompted naively
In production, combine 1 and 2 inline, reserve 3 for adjudicating borderline cases or for offline analysis. And when using an LLM to analyze suspect content, constrain the prompt aggressively and isolate the task: “classify this text for model-targeted instructions” is much safer than “summarize this document.”
Stage 5: sanitization and canonicalization
The sanitization step should create the version of content that downstream retrieval is allowed to see. This is not merely extraction; it is transformation under policy.
Common sanitization actions:
- Strip macros, scripts, embedded executables, and active elements.
- Convert office docs and PDFs to plain text plus structured markup.
- Remove or annotate hidden text and invisible layers.
- Normalize whitespace, encodings, and Unicode confusables where safe.
- Deduplicate repeated headers, footers, disclaimers, and boilerplate.
- Collapse OCR duplicates and remove low-confidence gibberish.
- Segment tables carefully or rasterize and re-extract if parser quality is poor.
- Redact or tag secrets/PII if your RAG tier should not expose them.
- Preserve page/section offsets to maintain citation traceability.
This is where retrieval quality and security align. Sanitized, canonical text improves chunking, embeddings, and rank stability while reducing attack surface.
A practical lesson: keep both a “forensics view” and a “retrieval view.”
- Forensics view: raw bytes plus detailed extraction artifacts for security and audit.
- Retrieval view: sanitized canonical representation approved for indexing.
Never let the retrieval view overwrite the forensics view. You need both.
Stage 6: staged indexing and release gates
The biggest architectural improvement over naive ingestion is staged indexing.
Instead of one monolithic index, use tiers:
- Quarantine index: accessible only to security/review tooling, not user-facing retrieval
- Candidate index: sanitized content available for automated evals and limited pre-production testing
- Production index: approved content for normal retrieval
- Restricted index: content allowed only for certain apps/users or with additional runtime guardrails
Release gates decide movement across tiers.
Example gate policy:
Gate A: Parse safety
- Detected file type supported
- No critical malware findings
- No parser crash anomalies
- Extraction confidence above threshold
Gate B: Content integrity
- Prompt-injection score below threshold or tagged restricted
- Hidden text reviewed or removed
- Boilerplate ratio below threshold
- OCR corruption below threshold
Gate C: Governance
- ACL snapshot valid
- Data classification compatible with target RAG app
- Provenance fields complete
- Retention/legal hold checks passed
Gate D: Quality and evals
- Chunking success rate acceptable
- Retrieval eval on sampled queries does not regress baseline
- Citation traceability intact
- No high-severity policy findings
This sounds heavyweight, but much of it can be automated. The key is to stop thinking of indexing as a write operation and start thinking of it as a release process.
Evaluation strategy: test the ingestion pipeline like a security boundary
Most RAG eval programs over-index on answer correctness, faithfulness, and task completion. For quarantine pipelines, you need a dedicated ingestion eval suite.
I recommend four eval categories.
- Security detection evals
Build a corpus of:
- Known malicious files or safe surrogates from security tooling
- Documents with macros, embedded objects, malformed structures
- Prompt injection examples from web and internal red-team exercises
- Hidden-text and obfuscated instruction samples
Measure:
- Detection rate by class
- False positive rate by source/type
- Mean time to decision
- Sandbox escape or parser failure events
- Sanitization fidelity evals
Measure whether canonicalization preserves useful meaning while removing dangerous or noisy elements.
Metrics:
- Text preservation score on benign docs
- Table extraction accuracy
- Citation offset stability
- Boilerplate removal precision/recall
- OCR cleanup quality
- Retrieval impact evals
Use representative query sets against candidate vs production index.
Metrics:
- Recall@k on trusted answer-bearing docs
- MRR/NDCG changes after sanitization
- Context pollution rate: fraction of retrieved tokens from low-trust or instruction-like chunks
- Citation quality and answer agreement
- Governance and provenance evals
Check that every chunk in candidate/production index has:
- Source identity
- Content hash lineage
- Parser/version lineage
- ACL lineage
- Scan attestation and decision trail
Treat missing provenance as a release failure.
A useful operational metric is quarantine yield: what percentage of incoming content reaches production, candidate, restricted, or blocked states. If production yield falls suddenly, either your threat environment changed or your policies/parsers regressed.
Provenance tagging is not optional
Every chunk in retrieval should carry enough metadata for three actions:
- runtime policy decisions
- incident investigation
- revocation and reindexing
Minimum chunk-level provenance fields:
- document_id and version_id
- source_system and source_uri
- ingestion timestamp
- content_hash and parent raw_hash
- parser_name/version
- sanitization_profile version
- malware_scan verdict/version/time
- injection_screen verdict/version/time
- trust_tier
- ACL snapshot id
- legal/data classification tags
- release gate decision id
At query time, this metadata enables important controls:
- Exclude low-trust tiers by default
- Down-rank recently ingested or weakly attested content
- Suppress instruction-like chunks even if semantically similar
- Filter by classification and app policy
- Show users provenance in citations to build trust
This is also how you do emergency response. If a parser CVE is disclosed or a malware signature improves, you can locate all chunks derived from vulnerable parser runs or previously missed files and revoke them.
Runtime retrieval policies should respect quarantine outputs
Quarantine is not just pre-processing. Its results should actively shape retrieval and generation.
Practical runtime policies:
- Filter out chunks with high injection scores from normal assistants.
- Allow restricted content only in apps designed for analysts with stronger prompts and tool restrictions.
- Use trust-tier-aware reranking so curated policy docs outrank unknown-origin near-duplicates.
- Add chunk-level warnings into the generation prompt only when needed, rather than passing raw suspect text.
- Refuse to summarize or transform raw quarantine content with broad-capability models before approval.
This is one of the most common mistakes: teams sanitize for indexing but let ad hoc tools query raw repositories directly for “just-in-time” summarization. That bypasses the entire trust model.
Model, tool, and cost tradeoffs
Engineering leaders usually ask: how much of this needs premium AI versus standard security tooling?
The honest answer is less AI than many vendors imply.
Use conventional security controls first for:
- malware scanning
- archive inspection
- file type verification
- sandbox isolation
- provenance and policy enforcement
Use AI selectively for:
- prompt-injection classification
- hidden instruction detection beyond simple heuristics
- semantic boilerplate identification
- retrieval impact analysis on candidate corpora
- borderline manual-review assistance
Cost and latency guidance:
- Inline AV and file inspection are cheap compared with repeated LLM passes.
- Small classifiers can score every chunk or document cheaply in batch.
- Frontier models are best reserved for disputed cases, offline eval generation, or reviewer copilots.
- Strong sandboxing adds infrastructure cost but usually in offline budgets, which is easier to absorb than interactive latency.
- Re-indexing after a contamination event is far more expensive than preventive quarantine.
A practical deployment pattern is:
- Synchronous fast path at ingest: file verification, AV, lightweight extraction preflight, heuristic injection screening, initial quality score.
- Asynchronous deep path: full sandboxed parse, OCR, richer classification, sanitization, candidate indexing, evals.
- Delayed release SLA by source trust: curated internal docs in minutes, external/vendor docs in hours if necessary.
Users rarely notice a one-hour delay in indexing external documents. They do notice when the assistant becomes untrustworthy.
Implementation details that matter more than they seem
Idempotency and replay
Every stage should be idempotent and keyed by content hash plus policy version. You will re-run documents when scanners update, parser bugs are fixed, or policies change. If you cannot replay deterministically, your operations will become chaotic.
Policy versioning
Store scanner versions, rule bundle versions, parser versions, and sanitization profile versions with every decision. “Why was this document admitted?” should have a concrete answer months later.
Dead-letter handling
Some files will always fail. Create explicit dead-letter states like unsupported_format, parse_timeout, encrypted_unopenable, suspected_malware, manual_review_required. Silent drops are unacceptable in enterprise search because users then assume absence means nonexistence.
Human review queues
Not everything can be automated. Give reviewers safe tooling: rendered previews from sanitized outputs, not direct opening of raw files on analyst laptops. Review UI should show risk signals, extraction diffs, and recommended disposition.
Document family logic
Many poisoning issues come from duplicate or near-duplicate families. Build family clustering using hashes, fuzzy text similarity, source lineage, and version metadata. Apply release decisions consistently across related artifacts.
Back-pressure and surge controls
During incidents or source floods, quarantine queues can spike. Plan bounded queues, source-specific throttles, and graceful degradation. It is better to delay indexing than to skip scans under load.
Observability: make trust visible
If you cannot see your quarantine pipeline, you do not control it.
Dashboards should cover:
- Ingestion volume by source, type, and trust class
- Scan verdict distributions and drift over time
- Parse failure rates by parser version and file type
- Prompt-injection score distributions
- Candidate-to-production promotion rates
- Mean time in quarantine by route class
- Revocation counts and reasons
- Retrieval exposure of low-trust chunks, ideally near zero for normal apps
Alert on:
- Sudden rise in MIME mismatches
- Spikes in hidden-text detections
- Parser crash regressions after deploys
- Production retrieval citing content later revoked
- Unusual source volumes from vendor or public connectors
Link these signals back to end-user quality metrics. Many “hallucination” incidents are traceable to corpus integrity regressions. If your observability separates model quality from content trust, triage gets much faster.
A realistic rollout plan
If your current RAG stack indexes directly from connectors, do not try to build the perfect quarantine platform in one quarter. Phase it.
Phase 1: establish quarantine boundaries
- Raw immutable staging
- Basic AV and file-type verification
- Separate candidate vs production index
- Provenance tags on all new chunks
Phase 2: harden parsing
- Sandboxed extraction workers
- Active content stripping
- Dead-letter and review queues
- Source-based routing policies
Phase 3: add content trust intelligence
- Prompt-injection screening
- Boilerplate/OCR quality scoring
- Trust-tier-aware retrieval policies
- Candidate corpus eval suite
Phase 4: operational maturity
- Revocation/reindex workflows
- Parser/scanner version replay
- Family clustering and duplicate control
- Executive dashboards tied to assistant incidents
This phased path delivers risk reduction early without waiting for a giant platform rewrite.
The core takeaway
Enterprise RAG failures from untrusted content are rarely just “LLM problems.” They are ingestion architecture problems, content governance problems, and security-boundary problems.
If you let raw, untrusted documents flow straight into parsing, chunking, and indexing, you are effectively allowing external and semi-trusted actors to shape your assistant’s grounding layer. That is too much power to grant by default.
A quarantine pipeline fixes this by making trust explicit. Raw bytes are staged immutably. Risk is scored before expensive work happens. Parsers run inside real isolation. Malware and prompt injection are screened separately. Sanitized canonical content enters staged indexes only after release gates pass. Every chunk carries provenance and attestation. Observability closes the loop so you can detect drift, revoke bad content, and improve policy over time.
This is not glamorous infrastructure, but it is the kind that determines whether enterprise RAG becomes a durable capability or a recurring incident source. Teams that treat corpus intake like a supply-chain problem usually end up with more trustworthy assistants, cleaner retrieval, easier audits, and lower long-run operating cost.
In other words: the safest answer your assistant gives often depends on controls that ran days earlier, before a single token was ever generated.