Security & compliance review

Your AI knows things this user must not see

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.

Sound familiar?

One corpus, every customer's data in it

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 security review is where pilots go to die

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.

Nobody can say what a typo actually does

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.

Why the usual fixes don't move the number

One shared vector index for everyone

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.

Folder-per-customer in the source system

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.

Filtering in the prompt ("only use Acme's documents")

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.

"We'll add real permissions later"

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.

How we solve it

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.

Tier: Enterprise | StandardJurisdiction: NY | CA | TXno free-typed values

02Two-level ACL, not one

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.

KB ACL: coarseDocument ACL: fine-grainedmirrored from source system

03A missing attribute narrows, never widens

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.

null → 0 documentsempty scope → refusesnames the scope

What you get on every document

Nothing to leak

Retrieval is scoped before the model ever sees a token, so there's no chunk to accidentally cite in the first place.

Provably scoped, not just configured

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.

Anonymous is a first-class case

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.

One index, many tenants, no crossover

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.

The obvious objections

Build your first agent with Inteleto