Skip to content

Engineering example / Engineering evidence

Engineering example: permissioned retrieval

Run a synthetic retrieval example with tenant and document access checks. Inspect permitted context, denied requests and the boundaries still untested.

Synthetic fixtures. Inspectable source and results.

The decision

This synthetic lexical retrieval example checks tenant and reader access before selecting content, checks citations at read time and invalidates cached evidence when a source is revoked, deleted or versioned. It demonstrates specific permission boundaries without claiming to be a complete RAG product.

  • Nine tests cover tenant, reader, cache and citation behavior.
  • The fixture uses current in-memory permissions and no model.
  • Authentication and distributed permission synchronization are outside its scope.

The problem: a correct answer can be an unauthorized answer

The fixture contains five documents in two tenants. Alice can read alpha’s finance document; Bob cannot. Carol can read beta’s finance document. The query “forecast” is the same for all three callers, but the allowed evidence differs. Access is applied before lexical ranking and context assembly.

The example follows a basic authorization principle: the application checks the requested resource for the current trusted caller. A query string or model output does not establish the caller’s tenant or group membership.[1]

A second scenario caches Alice’s answer, revokes her finance-document access and asks again. The cached answer cannot survive the changed dependency. A direct citation request also checks current access rather than bypassing the retrieval path.

Run and inspect the fixture

From the extracted retrieval-example directory
python3 -B -m unittest -v
python3 -B example.py

Use Python 3.10 or later. The example uses an in-memory corpus and the standard library. There is no model, vector service, network access or credential. The Principal objects represent already-authenticated caller context supplied by a trusted application; constructing one is not an authentication mechanism.

Version 2 prevents callers from changing cached source lists through an edited response. It also tests discovery after a new access grant when the previous answer had no accessible evidence. The original versioned download remains available for reproducibility; use this revised version for the current example.

How the boundaries are represented

Fixture components
ComponentBehavior
PrincipalImmutable tenant and user fields supplied by the trusted test harness.
DocumentTenant, allowed readers, content and version.
SearchCheck access before scoring and selecting document IDs.
CitationRecheck current access before returning source text.
Answer cacheKey by caller/query and record source-version dependencies.
RevocationRemove the reader and increment the source version.

On cache reuse, every source must still exist, remain readable and match the recorded version. Otherwise the answer is rebuilt from currently accessible evidence. Empty answers are not cached, so newly accessible evidence can be discovered after an earlier no-answer result.

Captured result from this source

Observed scenario output
{
  "alice_after_revocation": {
    "cached": false,
    "sources": [],
    "text": "No accessible evidence"
  },
  "alice_before_revocation": {
    "cached": false,
    "sources": [
      "a-finance"
    ],
    "text": "Confidential revenue forecast"
  },
  "alice_cached_read": {
    "cached": true,
    "sources": [
      "a-finance"
    ],
    "text": "Confidential revenue forecast"
  },
  "beta_result": {
    "cached": false,
    "sources": [
      "b-finance"
    ],
    "text": "Beta revenue forecast"
  },
  "bob_result": {
    "cached": false,
    "sources": [],
    "text": "No accessible evidence"
  },
  "fixture": "synthetic five-document lexical corpus; no model"
}

Alice initially receives a-finance and can reuse that cached result. Bob receives no accessible evidence. Carol receives only b-finance. After revocation, Alice receives no accessible evidence and the previous cached text is not returned. These are deterministic fixture outcomes, not a retrieval-quality benchmark.

What the nine tests establish

  • The same query returns tenant-scoped results.
  • A different reader in the same tenant cannot receive restricted content.
  • Revocation invalidates cached evidence.
  • Direct citation access follows current permissions.
  • A deleted source cannot survive through a cached answer.
  • A changed source version rebuilds the answer.
  • An unknown principal receives no evidence.
  • Edits to returned source lists cannot alter cached evidence.
  • A previously empty answer does not conceal a new access grant.

These tests inspect returned content and source identifiers, not only a boolean authorization response. A system can deny a document endpoint while still leaking its content through a snippet, summary or cached answer.

What a live design still needs

The fixture has synchronous in-memory policy and data. Real ingestion, identity, index and cache systems can have different update delays. Product-specific document-permission features may require source synchronization or explicit refresh; they should not be described as immediate revocation without verifying that contract.[2]

The example checks cached dependencies. Discovery of newly relevant documents, concurrent policy changes, distributed caches, ingestion attacks, prompt injection and generator output controls are each designed and evaluated as their own requirements.

Use the code to inspect a bounded principle: access is enforced before content is returned, and reused evidence is revalidated. Extend it only after defining the actual authority source, freshness requirement and failure behavior.

Sources and scope

Technical references inform the cited statements. The decision frameworks and synthetic examples are TeqEngine’s editorial guidance.

  1. OWASP: Authorization Cheat Sheethttps://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html
  2. Microsoft: Document-level access control in Azure AI Searchhttps://learn.microsoft.com/en-us/azure/search/search-document-level-access-overview

Have a system like this in front of you?

We can scope a platform engagement directly, or begin with an architecture review when the next decision needs more evidence.