How do you prevent cross-user data leakage by design?

Short answer: Make the system refuse wrong access structurally, and layer independent safeguards plus multi-user tests, not one forgotten filter.

Having isolation features available is not the same as always using them. By-design means no code path can reach another user’s data even if someone forgets a convention. Habits that skip scoping introduce leaks; repeated two-user tests catch them. Multiple independent layers reduce single-point failure. Engram combines structural scoping with additional safeguards.

The chapters so far in this Part have covered the individual pieces, scopes, project versus user isolation, property-scoped flexibility, the multi-tenancy mechanism underneath it all, and the distinction between hard and soft boundaries. This chapter pulls those pieces together into a single practical question: what does it actually take, concretely, to make sure cross-user leakage never happens, rather than merely hoping the pieces get assembled correctly?

Why Isn’t Simply Having Access to All the Right Isolation Mechanisms Enough to Guarantee Leakage Never Happens?

A system can have hard isolation available, multi-tenancy properly configured, and scoping properly designed, and still leak data if any single piece of code that touches memory forgets to actually use those mechanisms correctly. Availability of a safeguard and consistent application of that safeguard are different things, and a leak doesn’t require the underlying isolation architecture to be flawed, it only requires one code path somewhere to skip applying it. Preventing leakage by design means closing that gap specifically, not simply trusting that good mechanisms, once available, will always get used correctly.

What Does It Actually Mean for a Boundary to Be Enforced “By Design” Rather Than by Convention or Discipline?

Enforcement by design means the system itself refuses to do the wrong thing, rather than relying on every developer remembering the right thing to do every single time. A design that requires a user identifier before any user-scoped memory can be written or searched at all, rejecting the request outright if that identifier is missing, enforces the boundary structurally. A design that merely documents “remember to always pass a user_id” enforces nothing at all, it just hopes everyone reads and follows the documentation perfectly, forever, across every future change to the codebase.

What Specific Habits or Patterns Tend to Introduce Cross-User Leakage Even in Systems That Otherwise Have Good Isolation Available?

A common pattern is building and testing a feature against a single test user, where isolation gaps simply never surface because there’s no second user’s data around to accidentally leak into the results. Another common pattern is adding a new code path later, a new admin tool, a new batch job, a new integration, that touches memory directly without going through the same scoping conventions the rest of the system uses, quietly reintroducing exactly the kind of unscoped access the original design worked to prevent. Neither of these mistakes stems from a flawed underlying architecture, they stem from a gap between what the architecture makes possible and what every single piece of code actually does with it.

Why Does Multi-User Testing Deserve to Be a Standard, Repeated Practice Rather Than a One-Time Check?

A system tested only against one user’s data can pass every test while harboring a leak that would show up immediately the moment a second user’s data enters the picture. Deliberately testing that one user’s search genuinely returns nothing when searching for another user’s known content is the single most direct way to verify isolation actually holds, rather than merely assuming it does because the architecture supports it. This kind of test earns its place as a standard, repeated check, run every time a new code path touches memory, not a one-time verification performed once and then forgotten as the system continues to grow.

How Does Layering Multiple Independent Safeguards Actually Reduce the Risk of a Leak Compared to Relying on Just One Mechanism?

A single safeguard, however well-designed, is still one point of failure, and any one mistake in how it gets applied can undermine the whole guarantee. Combining structural isolation at the storage layer with role-based restrictions on who’s even allowed to issue certain kinds of requests in the first place means a mistake in one layer doesn’t automatically translate into an actual leak, since the other layer is still standing in the way. This is the same defense-in-depth thinking that shows up throughout secure system design generally, redundant, independent layers catching what any single layer might individually miss.

How Does Weaviate Engram Combine Structural Scoping With Additional Safeguards to Prevent Leakage by Design Rather Than by Convention?

Weaviate Engram enforces scope requirements at the point of every request, rejecting a call outright when a required identifier is missing, while Weaviate’s own role-based access control adds a further, independent layer restricting which credentials can even reach specific tenants at all. Consider a corporate legal-hold platform managing sensitive litigation documents for multiple law firms sharing the same infrastructure, where a leak between firms would be a serious professional and legal failure, not merely an inconvenience:

from engram import EngramClient

client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])

try:
    client.memories.search(
        query="What documents were flagged as privileged in this matter?",
    )
except Exception as e:
    print("Request rejected: missing required user_id for user-scoped topic")

results = client.memories.search(
    query="What documents were flagged as privileged in this matter?",
    user_id="firm-legalhold-3391",
)

The first call, missing the required user identifier, is rejected outright rather than silently falling back to some broader, unscoped search, meaning a developer who forgets to pass the identifier discovers the mistake immediately rather than shipping a quiet leak into production. Layered underneath this, role-based restrictions on which credentials can access which tenant at all mean that even a correctly scoped request from the wrong set of credentials would still be denied before ever reaching the data. This is exactly the value preventing leakage by design delivers for a use case like a shared legal-hold platform, where the cost of a single cross-firm leak is severe enough that isolation needs to be structurally guaranteed at more than one independent layer, not merely hoped for through careful, consistent discipline.

Preventing cross-user leakage by design means making the system itself refuse to do the wrong thing, layering independent safeguards so that no single mistake is enough to cause an actual leak. One of those independent layers, controlling which credentials are even allowed to issue certain kinds of requests in the first place, deserves its own closer look. Our next chapter, What is role-based access control for memory systems?, takes up exactly that layer.