Identity, SSO and RBAC
How identity is resolved, how permissions are evaluated at query time, and what happens when a permission source goes stale.
Permissions are evaluated when you ask, not when we index
The faster design filters at index time: stamp each document with who may see it, then search the pre-filtered set. We do not do that, because access control lists change and indexes lag.
Somebody leaves the finance team on Monday; the connector re-crawls on Thursday. For three days an index-time filter serves them finance documents, and every component is working exactly as designed. That window is where enterprise search leaks.
The rules
- Deny by default. Absence of a grant is a denial. Every failure — connector down, group unresolvable, tenant unknown — resolves to deny
- Deny beats allow, always, however many grants exist
- Stale permissions hide content. An access list older than the freshness limit makes the document invisible until it refreshes
- Nested groups resolve live, depth-limited and cycle-guarded; an unresolved branch denies rather than resolving optimistically
- An answer inherits the weakest permission of its sources. Filter first, then reason — never reason, then filter
- Result counts are computed after filtering. "47 results, 46 hidden" is itself a disclosure, and on a small corpus it can be a complete one
This produces false negatives: people will occasionally not find something they are entitled to, usually because a connector stopped and its content correctly disappeared. That is the trade we chose. A false negative is a support ticket; a false positive is a breach.
What we do not do
There is no administrator override. A support engineer debugging your tenant cannot read your documents; debugging works on metadata, counts and errors. This makes support harder and is not negotiable.
We do not cache answers across users. Two people asking the same question get two retrievals, because a cache keyed on the question alone is a cross-user leak.