01Labels come from a registry, never hand-typed
Keys and enum values are declared once per tenant. A value that isn't in the registry can't be assigned — so a typo can't silently create an empty, unevidenced join.
A shared corpus and a chatbot on top of it is how a pilot turns into an incident report. One missing attribute, one lender's guidelines answering another lender's question, and the deal that was about to close is now a security investigation.
Same question, two support agents, two different accounts. Priya's Enterprise-tier scope matches and cites the policy. Diego's Standard-tier account has no Enterprise scope — so it refuses and names exactly why, instead of guessing.
Guidelines for every lender, every client, every account sit in the same index because splitting it felt like overkill in the pilot. It stops feeling like overkill the day two customers ask why their competitor's terms showed up in an answer.
The demo goes great. Then someone from security asks how retrieval respects the identity provider's groups, and the honest answer is that it doesn't, yet — and the deal stalls for a quarter.
A label gets mistyped at ingestion — Lender: Chse instead of Chase — and nobody notices, because the join just returns nothing for that one document. Or, worse, a missing attribute matches everything instead.
Fast to build, impossible to sell past a security review. There is no way to prove after the fact who could have seen what, because nothing was ever scoped in the first place.
Folders don't survive a merge, a re-org, or a document that legitimately belongs to two matters. A document is found by what it is, not where somebody happened to save it.
A prompt is a suggestion, not a permission boundary. Nothing stops the model from citing a chunk that was retrieved anyway, and retrieval already happened before the model saw the instruction.
Retrofitting scoping onto a live index means re-tagging and reindexing every document you already ingested, under customer pressure, during the exact week you needed to look secure.
Keys and enum values are declared once per tenant. A value that isn't in the registry can't be assigned — so a typo can't silently create an empty, unevidenced join.
A coarse ACL gates the knowledge base; a fine-grained ACL mirrors the source system's permissions per document. Necessary, but never sufficient on its own.
Workspace.Tier == null does not match every tier — it matches zero documents. An empty required scope refuses to answer and names the empty scope, instead of guessing.
Retrieval is scoped before the model ever sees a token, so there's no chunk to accidentally cite in the first place.
Every Run records exactly which chunks were in scope for that caller, so a security reviewer can inspect the boundary directly instead of trusting a diagram.
A Run executes as a fixed service principal whose scope is set by the deployment; the caller's identity is input data, never a permission source — so an unauthenticated visitor can't escalate by supplying a fake identity.
Distributing a shared blueprint to sub-tenants copies it — it never shares by reference, so one client's corrections can't leak into another client's index.