
Show people the accounts they belong to
Account lists need their own boundary: an organization record is the account itself, rather than a record carrying a parent account ID. Wildo confines those collections to the caller’s organization-wide memberships.
A requested filter can narrow that set, but cannot turn it into a directory of other customers.
Example — Filter the account switcher
A person belonging to accounts A and B asks for B and C. The confined result can include B; the requested ID for C does not create membership.
For engineers
The same scope-root authority is used by authorization and repository filtering. After identifying a governed organization collection operation, it derives the allowed IDs from the caller’s organization-wide role entries and intersects the requested IDs:
This implementation excerpt from scope-root-collection-confinement.backend.ts shows the decision in context; explanatory source comments are omitted.
function intersectRequestedIdsWithMembership(requested: unknown, membershipIds: readonly string[]): string[] {
if (requested === undefined || requested === null) return [...membershipIds];
const membership = new Set(membershipIds);
if (typeof requested === 'string') {
return membership.has(requested) ? [requested] : [];
}
if (Array.isArray(requested)) {
return requested.map(String).filter((id) => membership.has(id));
}
if (typeof requested === 'object') {
const operators = Object.keys(requested as Record<string, unknown>);
const inValue = (requested as { $in?: unknown }).$in;
if (operators.length === 1 && operators[0] === '$in' && Array.isArray(inValue)) {
return inValue.map(String).filter((id) => membership.has(id));
}
return [];
}
return [];
}
Know which operations are set-shaped
The confinement covers list, search, count, update-many and delete-many operations on the organization root. Addressed reads have a separate per-record authorization path. A unit-only role does not become permission to enumerate the whole organization.
| Requested filter | Result within memberships A and B |
|---|---|
| No ID restriction | A and B |
| ID B | B |
| IDs B and C | B |
| An unsupported ID operator | No matching IDs |
The portable empty-set predicate produces no results on either database adapter. A caller-supplied condition is never a reason to drop the membership restriction.
Distinguish tenant lists from application directories
Other scope roots have explicit dispositions: the deployment application row, the person directory and anonymous sessions do not share the same tenant-membership filter. Application-wide directory admission has its own elevation policy. Internally initiated work, verified callbacks and deliberately admitted cross-tenant operations also have distinct handling; an empty membership list must not silently empty a framework maintenance sweep.