Permissions, Freshness, and Multi-Tenancy
In one line: an index built over everything, queried by anyone, is a data-leak mechanism with a natural-language interface — and the leak is untraceable because the model paraphrases.
Why this is worse than an ordinary access-control bug
In a normal system, an authorisation failure returns a record. The user sees a document they should not have, and it is at least identifiable as a specific document.
Here the model paraphrases the retrieved content into an answer. A salary figure from an HR document, a customer name from a support ticket, a clause from an unsigned contract — these appear as ordinary sentences with no indication of origin.
The consequence for the design is unambiguous: permissions are enforced at retrieval, before generation. Filtering the model's output afterwards cannot work, because by then the information has been rewritten and there is nothing to match against.
Two ways to model it
| Filter at query time | Partition the index | |
|---|---|---|
| How | Every chunk carries access identifiers; retrieval filters on the requester | A separate index per tenant or per group |
| Correctness | Depends on the filter always being applied | Structural — the data is not there |
| Retrieval quality | Degrades as selectivity falls | Unaffected — 100% selectivity within a partition |
| Scales to | Many groups per user, complex rules | Coarse boundaries — a tenant, an org |
| Failure mode | A missing filter leaks silently | Wrong index means no results, which is visible |
The failure-mode row is the argument. A forgotten filter leaks and looks normal; a wrong partition returns nothing and gets noticed immediately. Partitioning fails safe and filtering fails silent, which is why the coarse boundary should be structural wherever the access pattern allows.
And it inherits the vector search chapter's point: a tenant filter across many tenants sits far below the selectivity cliff where approximate search degrades. Partitioning removes both problems at once — correctness and recall — which makes it the answer to two questions with one decision.
The realistic design is usually both: partition by tenant, filter within it for the finer-grained rules that cannot be structural.
Permissions change, and the index does not know
The problem people miss. Access-control changes are not document changes, so nothing in the ingestion pipeline is triggered.
Someone leaves a team, a document is reclassified, a project's membership shrinks. The chunks are unchanged, so no re-index fires, and the stale access metadata keeps admitting the wrong people.
Storing a group identifier and resolving membership at query time keeps the index out of the authorisation business entirely. It costs a lookup per request, which is usually cheap next to retrieval, and it means permission changes take effect immediately rather than at the next re-index.
If you do denormalise permissions into the index for speed, permission changes must become an explicit re-index trigger — and that is a subscription to an event nobody thinks to publish.
Freshness
The same two-tier pattern as any index, with a RAG-specific wrinkle.
A large main index, rebuilt on a schedule, plus a small delta index updated continuously that every query also searches, with results merged. The delta stays small enough that exact search over it is fast.
The wrinkle is deletion. A document removed from the source must disappear from retrieval immediately, and the graph-index tombstone problem from the vector search chapter means it lingers in the structure. For an ordinary corpus that is a recall issue; for a document deleted because it was confidential or wrong, it is a correctness issue.
So deletions need to be applied as a hard filter at query time as well as a tombstone in the index, so a deleted document cannot be returned even before compaction.
Multi-tenancy, assembled
Putting the pieces together for the common B2B shape:
The audit line is worth its own mention. Logging which chunks were retrieved for which user is what makes an incident investigable later — and given the paraphrasing problem at the top of this lesson, it is the only record of what information actually reached someone.
Key takeaway
Retrieval turns an access-control failure into an untraceable leak, because the model paraphrases and the output carries no document identity — so permissions are enforced at retrieval, never on the output. Partition by tenant where possible, since a forgotten filter leaks silently while a wrong partition returns nothing and gets noticed, and partitioning also escapes the selectivity cliff. Store references to permissions rather than copies, so a membership change takes effect immediately instead of at the next re-index. And apply deletions as a query-time filter, because a tombstone alone leaves a withdrawn document retrievable until compaction.
Next: measuring the whole thing stage by stage.