An assistant answering questions over customer documents must never show one customer's data to another. Where should that control live?
Show the full answer Hide the answer
The deciding property
Whether the violation is detectable in the output. Toxicity, self-harm content and credit-card-shaped strings are detectable in text, so a validator can act on them. Another tenant's customer record is not detectable: it looks exactly like legitimate data, because it is legitimate data belonging to someone else. A filter has no basis on which to object.
So the control has to be upstream of retrieval, enforced with the end user's identity, in the data layer that already knows tenancy.
Why the other options fail
- A system-prompt instruction has no enforcement. The model is not a policy engine; it is a probability distribution over tokens, and any untrusted content in the context - a document a user uploaded, a page the agent fetched - can argue with the instruction. Treat instructions as guidance, never as a boundary.
- An output validator is a reasonable backstop and the wrong primary control here, twice over. First, it cannot tell whose data a plausible record belongs to. Second, by the time it runs, the data has already been placed in the model's context and in whatever request logs and traces that implies - so the disclosure has already happened to the model, the trace store and anyone with access to it.
- Human review scales badly and inherits the same problem: a reviewer looking at a response has no more basis than the validator for knowing the record is out of tenancy.
How to build it
The retrieval call carries the end user's identity rather than a service identity, and the index is filtered by tenant before the nearest-neighbour search rather than after it. Pre-filtering matters for correctness and for quality: filtering after an approximate search returns whatever survives from the global top-k, which for a small tenant can be almost nothing, so a post-filter silently degrades recall as well as leaking the question of what was retrieved.
Then layer the cheaper controls behind it: per-tenant index partitions where volumes justify them, a validator that blocks responses containing identifiers not in the requesting tenant's set (a check that is decidable), and an audit record of every document id placed in a context.
What would flip the decision
| If this changes | Choose | Because |
|---|---|---|
| The policy is about the response's character - toxicity, legal advice, a refusal category | An output validator | Those violations are decidable from the text alone |
| The retrieval corpus is single-tenant and public | No tenancy control at all | There is nothing to isolate; adding one adds failure modes |
| The agent can call tools with side effects | An authorisation boundary per tool, with the user's identity | The same argument as retrieval, applied to writes, where the consequence is worse |
What it costs
Request-scoped identity through the retrieval path means no shared cache keyed only by query text, so cache hit rates fall and some latency returns. Pre-filtering an approximate index is more expensive than post-filtering, sometimes markedly so for highly selective filters. Both costs are the price of a control that holds, and they are cheap next to the alternative - a filter that must be correct about something it cannot determine.
When this is the wrong placement
When the corpus is single-tenant or public, there is nothing to isolate and a tenancy check adds a failure mode for no benefit. And when the policy is about the response's character rather than its ownership - a refusal category, a tone requirement, a legal disclaimer - the validator is the right and only workable place, because those properties exist in the text and nowhere upstream.