PSEEDR

The AI Assistant Passed the Permission Check. Its Cached Answer Did Not.

An AI assistant can return restricted information from a cached answer even when its data service correctly denies access. Acceptance tests have to cover reused answers, every returned field and changes to user permissions.

· 11 min read · PSEEDR

A blue answer card bypasses a closed document gate while a white sheet remains blocked. Text: Access denied. Answer leaked.

Watch the analysis

Watch the full video on YouTube · Watch the Short

The second account was denied access to the note. It still received information from it.

Pravin Nagare, lead software engineer at Roku, Inc., described an internal assistant pilot run in early 2026 at what he called a major consumer streaming platform. He did not name the platform. Engineers used the assistant to look up subscription incident notes. Some notes were shared across teams; others were restricted. The backend passed a delegated user token to the data service, which validated it and applied the user's existing permissions before returning any text to the assistant. The model was not allowed to choose which user it was acting for.

The team then tried the same question with two test accounts. One could read a restricted note; the other could not. Direct retrieval correctly denied the second account, but a cached answer still included information from that note. The data service had refused to retrieve the note, yet the application still held information from it in a prepared answer, ready to return.

Nagare said the team removed the shared answer cache for restricted content, repeated the test in both account orders and tested again after revoking access. In those tests, restricted material stayed out of the response while notes both accounts could read remained available. That was enough to keep the pilot moving. He did not present it as proof that every permission edge case was covered.

For a team deciding whether to accept a shared assistant, the usual acceptance evidence leaves one question unanswered: does the complete response, not only the original lookup, respect the recipient's permissions? A useful answer and a data service that denies the wrong caller can both be true while information has already been copied into a stored answer, assembled into a response or still held after the user's access was removed.

Reusing an answer creates another access decision

An answer cache stores prepared answers so an application can reuse them instead of querying the data service again. If a stored answer contains information from a restricted note, returning that answer discloses that information without any new retrieval. The data service never sees the second request, so its correct denial cannot protect a copy it is no longer asked about.

"A cached answer needs the same access protection as the records behind it," Nagare wrote in his response to PSEEDR.

That requirement travels with the information. An answer may summarize one source or combine several, and it still conveys restricted material. It does not become suitable for every user merely because it is newly worded. Before returning a stored answer, the application has to account for what the answer contains and what the recipient may see.

Removing shared answer caching for restricted content was the fix Nagare reported. Other designs may scope cached answers to users or to permission sets, but this case does not establish which cache design would be sufficient, and it does not identify the cache technology or how stored answers were matched to requests. A user-specific cache can keep two users apart and still return old information to one of them after that user's access is removed. Separating users and responding to permission changes are different checks.

HTTP caches are a separate consideration. RFC 9111 restricts when a shared HTTP cache may reuse a response to a request that carried an Authorization header. Those rules govern HTTP caches along the request path. They do not configure an application's own store of generated answers, so a response header is not, on its own, a remedy for that store.

To test answer reuse, let the authorized account ask first, then submit the same question under the unauthorized account. Repeat in the opposite order. Inspect the complete response and establish whether a stored answer was used. If the test never exercises reuse, a clean result says little about the cache path. A passing result covers the accounts, content and request variations tested; Nagare made that limit explicit, and it belongs beside the result.

Keep the user's authority at the data service

The cache failure does not make the original permission check less necessary. It shows why that check must sit inside a wider test of what reaches the user. First establish whose permissions the data service applies, then examine the routes that can return information beyond what that check approved.

Scott Stouffer, co-founder and CTO of Market Brew, described the company's read-only Model Context Protocol (MCP) connection, made available in October 2026. MCP lets compatible assistants call connected services. In his account, users connect their own Market Brew accounts through OAuth. Requests carry that user's authorization, and the data service applies the existing account and portfolio membership permissions. The assistant's wording does not decide what the user may see. Stouffer disclosed that he co-founded the company whose integration he used as his example.

He said the company tests both sides of the boundary: an authorized request works, and a request crossing into another user's customer data is denied. The positive case matters because a system that denies everything can pass a denial test while failing the task it was built for. Read-only access still needs the negative case, because disclosure does not require editing or deleting a record. He offered no incident rate and did not claim that a test suite proves every possible request safe.

The OWASP Authorization Cheat Sheet distinguishes authentication, which verifies identity, from authorization, which decides what that identity may access. It calls for permission validation on every request and for enforcement on the server side. For an assistant, that means evaluating the actual caller and the requested information at the data service, rather than relying on the model to obey a description of who should see what. A test performed only with a broadly privileged developer account can show that the connection works while leaving the intended user restrictions untested.

Carrying user authority through several services does not mean forwarding one token everywhere. The MCP authorization security specification dated July 28, 2026 requires an MCP server to validate that an incoming token was issued for it. If that server calls an upstream API, it uses a separate token issued for the upstream service; the incoming token must not be passed through. The contributed accounts do not reveal enough detail to assess their implementations against that specification.

Sudhanshu Dubey, delivery manager and enterprise solutions architect at Errna, described another way to enforce the caller's scope. In a multi-tenant retrieval system, middleware took organization and security-clearance claims from OpenID Connect tokens and inserted them as mandatory filters on the database query. In validation in early 2024, he said, an injected instruction to fetch another client's material returned no results because the filter still applied. He also reported that complex attribute filters created a latency problem, which the team resolved by changing how those attributes were indexed; he gave no measurements.

That empty result supports the filtering path he described. It does not answer the cache question, because a filter on a new database query cannot determine what a previously prepared answer contains, and it does not show that prompt injection cannot bypass other components. Each control needs evidence from the path it actually governs.

A permitted object can contain restricted fields

Not every disclosure requires a cache. An application can retrieve a resource the user is allowed to see and then include restricted information when it assembles the response.

Runbo Li, co-founder and CEO of Magic Hour, described this problem in an early-2024 template API at the AI video company. It was an adjacent API case, not an account of an assistant deployment. Users could save and remix video workflows whose templates referenced uploaded assets, settings and generation history. Li said the backend resolved the user's identity from the session, server-side, before any data query ran, and applied row-level access checks.

A shared template looked correct in the preview, yet its response payload included private asset metadata belonging to the template's creator. Tests with two accounts exposed the leak by comparing complete response bodies rather than the visible output. According to Li, the team caught it in staging and added a serialization layer, the step that prepares data for the response. That layer filtered fields according to the requesting user's permission scope rather than only the resource's ownership.

"Never trust the rendering layer to enforce access control," Li wrote.

The user was allowed to load the shared template. That permission did not extend to every piece of related information about the creator's assets. The preview could look correct because the interface displayed only part of what the endpoint returned, so filtering the visible page would have left the extra fields in the underlying response.

OWASP's guidance on object-property authorization addresses this distinction: allowing access to an object does not authorize access to all of its properties. It recommends selecting the properties a response should expose instead of returning the object's whole representation, with response-schema validation as another layer of protection.

For an assistant, the response may include citations, source references and metadata as well as answer text. Which fields are restricted depends on the application's policy. The test needs to establish that policy and inspect the actual fields against it, while confirming that the permitted resource remains useful. A screenshot cannot establish what the full response disclosed.

Removing access must reach copies of the permission data

Testing two users checks a difference between identities. Revoking one user's access checks a change over time. An application can handle the first correctly while continuing to use an outdated permission record or a stored answer for the second.

The version of Microsoft's Azure AI Search document-access overview reviewed for this article in October 2026 describes native permission options under the August 2026 preview API. Query-time enforcement compares the caller's claims with permission metadata stored in the search index. Permission changes in the source system affect search results only after that metadata is synchronized to the index, and the documentation states that a timing lag occurs before changed restrictions are recognized.

The important distinction is where the permission changes and where the permission check runs. If the source has removed a user's access but the index still holds the earlier permission record, a correct check against that copy gives an outdated answer. Disabling an answer cache does not update the index's permission data. Updating the index does not establish that a separately cached answer has been removed or made unavailable. Each copy has to be checked on its own.

This is a documented constraint of the described permission model, not a measured delay in the contributors' systems or a claim that every search service behaves the same way. It gives the revocation test a concrete sequence: make a permitted request, remove access, then examine direct retrieval and any route that can reuse prepared material. Record when the source policy changed, when the relevant permission data updated and what the application returned in between.

A test performed only after every copy has updated cannot show what happened during the interval, and "revocation passed" can then describe several materially different behaviors. The purpose is to compare observed behavior with the access policy the application is supposed to enforce. If that policy requires tighter revocation than the implementation provides, the gap is a product and engineering decision; a successful sign-in does not settle it.

Accept the complete response, including the paths that reuse it

The cases point to a small set of complementary checks. This is PSEEDR's synthesis of the contributed accounts and the primary guidance, not a test suite we ran or a certification standard.

Condition to exercise What to inspect What a passing observation supports
Two accounts have different private access and some shared access The same request and complete response under each identity Permitted information remains useful, and the tested private information stays restricted
One account populates an answer cache before the other asks; then reverse the order Answer text, references, metadata and evidence of reuse The tested cache paths preserve the access boundary
A shared resource refers to private material Every returned field, not only the rendered view Access to the shared resource does not expose the disallowed fields tested
Access is removed after a successful request Direct retrieval, reusable answers and permission-update timing The observed removal behavior across those paths and times

These checks answer different questions. The data-service test shows what a query can retrieve. The full-response check shows what the application actually delivers. The reuse and revocation checks show whether an earlier answer or permission decision survives into a request where it no longer belongs. Each failure described above became visible only because someone tested a path the others did not cover.

OWASP also notes that unit and integration tests help detect access-control flaws but do not replace dedicated security testing. None of the contributed accounts establishes an incident rate or exhaustive safety. Their value is more specific: they identify failures that a useful answer and a correctly denied lookup can both miss.

The decisive evidence for accepting an assistant is a useful response to a permitted request and the absence of restricted information from a denied one, across every route the application uses to deliver an answer. Nagare's pilot passed that test for the accounts, orders and revocation it tried, after the team removed its restricted-content shared cache. The earlier failure explains why the test had to extend beyond the database: a correct permission check can coexist with an unauthorized answer.

Sources