Skip to content
Insights · Generative AI

When a customer sees another's answer

Another customer's text is already in an answer. Turn retrieval off, keep the trace, and see whether the tenant filter failed once or everywhere.

Scroll
Generative AIOct 13, 20269 min readBy Salman Naqvi, Founder & CEO
When a customer sees another's answer

Another customer already saw someone else's content in an answer. In the first hour, turn off the path that retrieves text for anyone, keep the trace of the request that leaked, and find out whether the tenant filter failed on that one query or on every query of that shape. Do not start by editing the system prompt. A line that says "never reveal another customer's data" is not a boundary between tenants. It is a wish, and the answer that already went out is the evidence the wish was not the control.

This is the stop. It is not the five checks for a wrong answer drawn from the right corpus, and it is not the list of what you should have retained after a bad reply. Those start once the feature cannot leak a second time. While it can, diagnosis is how a second customer learns a third customer's name. The order is the whole method: stop, keep, then count. Whether any live feature should still be answering is when to turn a live AI feature off. That rule has already fired: another customer's text moved. What follows is the first hour of that stop.

Turn the retrieval path off before you understand it. Leave the rest of the product up if it does not read the index: login, billing, the pages that do not call the model. Kill or refuse the route that assembles an answer from stored text. A maintenance banner is a courtesy. The control is that the route returns nothing from the corpus. Teams leave the route up "while we look" because the look feels responsible and the outage feels like an admission. The admission has already happened. The look is how it happens again. A kill switch with a named owner is one of the four things a proof of concept is built to skip, and the trip from proof of concept to production is where that absence usually becomes visible. If the switch does not exist, the first hour includes someone who can actually revoke the credential or the route, not a channel where people agree that someone should.

Keep the trace of the request that already failed. You need the question the user asked, the chunk identifiers that were returned and which tenant each chunk belonged to, the prompt that was sent, and the answer the user saw. Deleting logs to "contain" the incident destroys the only record of how far it reached. Containment is the route being off. The log is how you learn whether you owe one customer an explanation or a page of them. What a trace has to contain, and why the default observability library will not have opted you into the prompt text, is what to keep after a wrong AI answer. Do that reading after the route is dark. Do not do it instead.

Four places the other tenant's text can enter, in the order you check them. First, the retrieval filter omitted the tenant. The right document for the wrong customer was eligible, so the ranker did its job and the job was the bug. Second, a cache or a vector store was keyed on the question alone, and an earlier tenant's result was served to a later one. Third, something upstream of the model — a shared scratch file, a notebook export, a prompt template with a pasted example — carried another customer's row into this request. Fourth, and only after the first three are written down as passed or failed, the model may be repeating something from training. That fourth case is the one everyone wants to debate, and it is the one you are least able to act on tonight. The first three are your code.

OWASP's 2025 entry on sensitive information disclosure names the failure in a single scenario: "A user receives a response containing another user's personal data due to inadequate data sanitization" (OWASP Gen AI Security Project, LLM02:2025 Sensitive Information Disclosure). The same page is explicit about the fix people reach for first. Adding restrictions in the system prompt about what the model should return "can provide mitigation against sensitive information disclosure. However, such restrictions may not always be honored and could be bypassed via prompt injection or other methods." Read the second sentence as the reason the prompt edit waits. A mitigation the publisher of the risk says can be bypassed is not what you ship while the route is still on, and it is not what you tell a customer you did.

Who may log in is a different control from where a chunk may travel. NIST SP 800-53 Revision 5, control AC-4, is information flow enforcement: enforce approved authorizations for controlling the flow of information within the system and between connected systems, based on the organisation's flow policies. The discussion draws the distinction in one clause. Information flow control "regulates where information can travel within a system and between systems (in contrast to who is allowed to access the information)" (NIST, SP 800-53 Rev. 5). A customer who is allowed to use the assistant has passed the access check. They have not been granted a flow that carries another tenant's chunk into their answer. A login that works, and a filter that does not, is AC-4 failing while the sign-in page looks healthy. Do not spend the first hour resetting passwords.

The same class of bug is ordinary in ordinary software, which is why the first hour is a test and not a theory of models. In the OWASP Top 10 for 2021, the A01 broken-access-control row lists a maximum incidence rate of 55.97% and an average incidence rate of 3.81% (OWASP, A01:2021 – Broken Access Control). Those are not two names for one number. The maximum is the highest rate reported by any single contributing dataset. The average is the average across the contributed data. A sentence that quotes 55.97% and drops 3.81% has misread the table. The page's prose also says 94% of applications were tested for some form of broken access control; the table's maximum-coverage cell is 94.55%. Tested is not the same word as vulnerable. What the row is doing in this article: a missing tenant filter is a member of a weakness class programmes already measure, with an average incidence that is not rare and a maximum that is easy to misuse. Your incident is one system. The table is why you look at the filter before you look at the model, not a rate you paste into the customer note.

Count the blast radius before you write the story. Take the question shape that leaked. Run it as three other pairs of tenants, against the same index, with retrieval still off for real users and on only for this test. If a second pair leaks, the filter is absent, not unlucky, and the notice you owe is wider than the person who wrote in. If the other pairs hold, you still do not declare the system safe. You declare that this shape, on this sample, did not reproduce, and you keep the route dark until someone can say which line enforces the tenant on every query, including the cache key. A sample of three is not a proof. It is how you stop yourself telling one customer "we think it was just you" when you have not looked.

Tell the customer who was exposed, and the customer whose data moved, on a different clock from the root cause. They are waiting to learn whether they have to tell their own customers something. The first message can say what was seen, what you have turned off, and when you will write again. It does not have to name the missing filter, and it should not name a cause you have not checked. Which statute, if any, that message also has to satisfy — and the ways founders confuse an outage with a reportable breach — is what you owe a customer when your product breaks. Use that for the legal clock. Use this article for the technical order. Mixing them is how a team spends the first hour drafting a perfect explanation of a route that is still live.

There is a version of this page that should not turn into a rescue engagement. The text the user saw was their own document, retrieved badly or ignored — that is a wrong answer from the right corpus, and the five checks for it are what to check when a production RAG answer is wrong. You do not yet have two tenants, so there is no cross-customer flow to enforce — the design of authorisation, before anyone is hurt, is the prototype article, not an incident. Nothing is in production and nobody has seen a leak. You want an AI readiness assessment, not a war room. And if the only desire in the room is a demo that impresses a buyer once, a kill switch and a tenant filter are scope that buyer has not asked for. Say so.

When the answer is already in a customer's hands, the route is dark, and the first three entry points point at a filter or a cache you cannot see from the chat window, the remaining work is specific. An audit of which queries were eligible to cross a tenant boundary. A test that fails the build if a chunk from tenant A can be retrieved as tenant B, including through the cache. A guardrail that refuses to answer rather than guessing across that boundary. One baseline — cross-tenant retrievals at zero, measured, not asserted — agreed before the rebuild. That is what an AI pilot failed to reach production engagement is for: finished in 8–12 weeks, with the audit in the first week or two, so a pilot that cannot keep tenants apart is called unsalvageable before the larger invoice starts. The metric is agreed up front. If the engagement does not move it, the build is on us and you do not pay for it.

What multi-tenant actually has to mean, once more than one customer shares a system, is visible in Veritas AI, a fraud-detection API packaged as a multi-tenant SaaS: the platform is built so one subscriber's traffic is not another subscriber's data, with role-based access tied to the subscription and monitoring on the API that serves them. The case is not a claim about a leak, and it is not a rate. It is the shape of the control this incident is missing — isolation as a property of the request, not as a sentence in the prompt. The harness that keeps that property from regressing on the next release is AI evaluation and observability.

Turn the route off. Keep the trace. Check the filter, the cache key, and the prompt assembly, in that order, and write down what each one did on the request that leaked. Then run the same shape as three other pairs before you tell anyone it was a one-off. The prompt edit, if you still want it, comes after a control that does not depend on the model obeying.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→