The RAG Permission Blind Spot Nobody Tests For
Retrieval-augmented generation collapses your access-control model into a single answer box. Most teams test whether the model retrieves the right information. Almost no one tests whether it retrieves information the asking employee shouldn't see.
The setup that creates the gap
A typical internal RAG pipeline looks simple from the outside: documents get chunked, embedded, and stored in a vector index; a query comes in, the most similar chunks get retrieved, and a model turns them into an answer. What's easy to miss is that the vector index rarely inherits the permission model of the systems those documents came from.
Source systems — a wiki, a shared drive, an HR platform — almost always have some notion of who can see what. The index built on top of them, in a lot of first-generation RAG deployments, does not. Once a document is chunked and embedded, it's just vectors in a database. Unless someone deliberately carried the permission metadata through the pipeline and enforced it at query time, retrieval will happily surface a chunk from a document the querying employee was never allowed to open directly.
Why this stays invisible in normal testing
Functional testing asks "did the model retrieve something relevant and answer correctly?" That's a different question from "was the requesting user entitled to see the source of that answer?" A RAG system can pass every accuracy benchmark a team throws at it while silently ignoring access boundaries, because nothing in a typical eval harness checks permissions — it checks relevance.
It also doesn't show up in casual use. An employee asking about vacation policy gets a correct, permitted answer. The gap only appears when someone asks a question whose best-matching chunks happen to live in a document they shouldn't have access to — compensation data, an active HR investigation, a pre-announcement M&A memo. That's a low-probability event in day-to-day use, which is exactly why it survives unnoticed until a red team goes looking for it, or an attacker does.
What a real test for this looks like
Testing for this isn't about jailbreaking the model — it's about mapping. The core exercise is straightforward to describe and genuinely tedious to do well:
- Enumerate the actual permission boundaries in the source systems feeding the index — who can see what, in the tools where the documents actually live.
- Create test identities at each permission tier, and issue queries specifically crafted to pull from documents outside that tier's access.
- Check not just whether the model refuses, but whether the retrieval step itself ever surfaced the restricted chunk into the model's context at all — a refusal after the fact doesn't undo the exposure if the content already reached the prompt, logs, or a trace.
- Repeat as documents are added, moved, or re-permissioned — this isn't a one-time test, because the index drifts from the source of truth continuously as content changes.
The fix is architectural, not a prompt
The sustainable answer isn't a system-prompt instruction telling the model to "only use authorized information" — that's asking the model to self-enforce a boundary it was never given the information to enforce correctly. The fix is retrieval-time filtering: carrying permission metadata through the ingestion pipeline and applying it as a hard filter before chunks ever reach the model's context, plus periodic reconciliation between the index and the source systems' actual current permissions.
None of this is exotic. It's the same access-control discipline every one of these organizations already applies to the source systems themselves — it just has to be extended one layer further, into the index, deliberately, rather than assumed to carry over automatically.