The caller is identified
Over HTTP, each request carries its own validated token. The token maps to scopes such as one repository or one wiki, and a policy maps scopes to roles. With no identity, or an identity with no roles, nothing is returned.
Give an AI assistant access to your engineering record and it can quote anything it finds. Muninark filters by the caller’s scopes before results reach the model, and logs each tool call.
Whatever a retrieval layer returns, the model can repeat. If that layer ignores who is asking, one agent with broad access can leak a confidential record to a person who could never have opened it.
Access is decided before retrieval results are ranked, assembled or shown to a model. Nothing relies on the model to hold anything back.
Over HTTP, each request carries its own validated token. The token maps to scopes such as one repository or one wiki, and a policy maps scopes to roles. With no identity, or an identity with no roles, nothing is returned.
A record is readable only if one role covers both its sensitivity level and one of its scopes. Everything else is dropped before ranking, before evidence is assembled and before any model sees it.
The model receives only evidence the caller may read. That does not guarantee that every statement it generates is supported by that evidence.
Each tool call, answered or refused, adds a record to a tamper-evident log: who called, which tool, the outcome, the roles in force and the evidence cited. If a record cannot be written, the call is refused. Authentication failures are logged separately.
Filtering search results is the easy part. These cover other paths to the same records.
When nothing matches and when a match is withheld, the response is byte for byte identical across the 22 tools that use it. Tests cover that one property of the response. They do not establish resistance to every way of probing for what exists, and timing is not covered in general.
When the build merges source records into a summary or a decision, it never combines records with different scopes. A derived item is therefore never readable by more people than its sources.
The archive reader checks access to both the archived copy and the current revision of the record. Point-in-time search is currently switched off.
Run on the public microsoft/semantic-kernel repository, split into three scopes: source code, pull requests and wiki. Muninark is not affiliated with Microsoft.
Each cited reference was resolved to its record and compared with the caller’s scopes. One shared scope is enough to pass, and any evidence with none counts as a leak.
The test also counted over-refusals: questions the caller should have been able to answer, returned without that evidence. For the caller holding all three scopes this was 13 to 16 of its 54 questions, and for single-scope callers between 1 and 5. These are expected-visible questions that came back without evidence for the expected scope. The run report ties some of the changing results to the retrieval relevance threshold, not to the access check.
The test checks the evidence references, not the wording of the answers. It covers one tool, search, on a public corpus with no private data, and it does not test timing or hostile queries. Ten subjects that span several scopes were left out of the question bank.
These limits depend on how a deployment is configured and on the records it holds.
Security and deploymentTell us which teams and sources must stay separate, and we can walk through how the scopes would be set.