TL;DR: Attach access-control information to every chunk at ingestion, resolve the user's identity and groups at query time, and filter the search to permitted chunks before ranking, so nothing forbidden reaches the model. Never rely on the model or the prompt to withhold content. Sync permission changes quickly, treat stale permissions as a severity-one incident, and test permission correctness automatically with synthetic users.
Why permissions are the core design constraint
A RAG assistant over company documents is only as safe as its retrieval layer. If retrieval returns a chunk from the board's acquisition plans or the HR salary review to an employee who cannot open those documents, the model will use it, and the answer will leak it. One such incident can end an enterprise deployment.
Language models cannot be trusted to keep secrets they have been shown. Instructions such as "do not reveal confidential content" are not a security control: the model may ignore them, and prompt injection can override them. The only reliable approach is that forbidden content never enters the prompt.
The design
Capture access at ingestion
Connectors pull each document's access list from its source system: individuals and groups who can view it, sharing settings, inherited folder permissions. Every chunk derived from the document carries that list (or a reference to it).
Filter before retrieval
At query time, resolve the user's identity and group memberships, then restrict the search to chunks the user can access as part of the query itself. Filtering after retrieval (fetch top results, then drop forbidden ones) is weaker: it can return fewer results than expected, reveal through counts or timing that hidden content exists, and if the post-filter has a bug, forbidden content reaches the model.
Keep permissions fresh
Access changes constantly: people change teams, documents are restricted after an incident, contractors leave. The index must reflect changes quickly. Event-driven sync where sources support it; short polling cycles otherwise; and for highly sensitive sources, checking permissions live at query time. A permission change that takes a day to propagate is a day-long leak window. Treat stale permissions as an incident class with an owner and alerting.
Do not hint at hidden content
"There is a document about the reorganisation you do not have access to" is itself a leak. When nothing permitted answers the question, the assistant says it could not find an answer.
Tenant isolation
In multi-tenant products, customer boundaries come before user permissions. Tenant ID on every chunk, enforced inside the retrieval service so no caller can omit it, or separate indexes per tenant. Caches, logs, evaluation sets and any fine-tuned models must respect the same boundary.
Indirect leakage paths
| Path | Example | Control |
|---|---|---|
| Caches | Answer generated for one user served to another | Cache keys include user or permission scope; avoid caching permissioned answers |
| Summaries and derived content | A pre-built summary of a folder includes restricted files | Derived artifacts inherit the strictest source permissions |
| Logs and analytics | Engineers browsing traces see restricted content | Access controls and redaction on traces |
| Agents with tools | An agent fetches a document through a tool with broader credentials | Tools act as the user, never as a service account |
Testing permission correctness
Permission correctness should be tested like any critical security property:
- Synthetic users in different groups, with known access, run queries designed to retrieve restricted content. Expected result: never returned.
- Canary documents containing unique marker phrases, restricted to specific groups; automated checks that markers never appear for others.
- Tests after every connector change and on a schedule.
- Freshness tests: change a permission in the source, measure how long until retrieval reflects it.
The target is 100%. Unlike quality metrics, there is no acceptable failure rate.
In the interview
Enterprise RAG and AI search design questions are often decided by this concept. The strong answer raises permissions before anyone asks, places ACL capture at ingestion and filtering before retrieval, insists that the model is never the authorisation system, treats freshness as an incident class, and describes automated permission tests. Mentioning that the assistant must not hint at hidden content is a detail that shows real experience.
Next: RAG explained · the confused deputy