Skip to content

Authorize retrieval before evidence reaches the model

Implement a deny-by-default evidence policy for a shared support index. Check tenant membership, object access and the draft recipient before context construction, then handle stale permissions, cached answers and in-flight work explicitly.

24 MIN

By AISecurityInterviews · Updated

TL;DR: Authorize evidence before it reaches a model, log or recipient outside its permitted boundary. Scope candidate retrieval, enforce current object permissions and distinguish staff research from a customer-facing draft. Tenant/user cache keys help separate users but do not keep cached permissions current.

Where you are. Module two, lesson one. You will turn the case's permission table into an executable policy and a revocation test matrix.

Decide whose task this is

Mina's customer chat and Aria's internal investigation have different evidence scopes. A third task, drafting a reply to Mina, needs evidence suitable for that recipient. Treat the task type as an application policy choice. The model cannot promote a customer answer into a staff investigation by proposing a different label.

Derive the actor from verified authentication, then resolve current membership and object grants. A tenant selector from a request may identify a desired workspace, but the service must confirm the actor belongs to it. A signed token can still carry stale role information; choose how role changes reach the authorizer and what happens while that service is unavailable.

An application service credential is not intrinsically wrong. It becomes dangerous when a caller can use its broad reach without mandatory user and task checks. Prefer storage constraints and narrow service permissions where available, then enforce the remaining object rules in a shared access layer. A delegated user token still needs the same business-policy decisions.

Scope retrieval and enforce the final evidence gate

Use a tenant-scoped query to reduce candidates and avoid retrieving irrelevant private material. Apply object-level rules before unauthorized text reaches a model, reranker, trace or caller. If a search engine's permission metadata can lag the source, either give that metadata an adequate freshness guarantee or check current authoritative permissions before exposure.

Post-filtering inside a properly isolated, mandatory authorization service can enforce a boundary. It is not automatically a leak. Its disadvantages may include sensitive candidates entering more infrastructure, poor recall and bypass risk if some callers can omit the filter. Pre-filtering is useful but not sufficient when its policy is stale or wrong. Review the actual data path rather than treating the filter's name as a security property.

EVIDENCE AUTHORIZATION
Search candidates do not become context automatically

Verified actor

Resolve current membership

Scoped candidates

Tenant and task constraints

Evidence gate

Current object and recipient policy

Permitted context

Dispatch under processor policy

1/2

Separate selection and permission

Relevance selects candidates. The evidence gate decides which records may cross into this task’s context.

A per-tenant namespace also helps only if callers cannot choose an arbitrary namespace or use a credential that bypasses the intended routing. “Separate index” is a design detail; the enforced boundary is who may query which data.

Run a small policy model

This offline example models four records and current membership. It does not implement authentication, vector ranking, storage isolation or distributed revocation. The document reader lists stand for authoritative object grants. For a customer draft, both the staff actor and the intended recipient must be allowed to read every selected record. A real product may have a separate disclosure policy; represent that explicitly instead of assuming a read grant covers delivery.

from dataclasses import dataclass


@dataclass(frozen=True)
class Actor:
    tenant: str
    user: str


MEMBERS = {"alder": {"mina", "noor", "aria"}, "birch": {"eli"}}
DOCS = [
    dict(id="help", tenant="alder", published=True, readers=set()),
    dict(id="mina-ticket", tenant="alder", published=False,
         readers={"mina", "aria"}),
    dict(id="noor-ticket", tenant="alder", published=False,
         readers={"noor", "aria"}),
    dict(id="birch-ticket", tenant="birch", published=False,
         readers={"eli"}),
]


def may_read(actor, doc):
    if actor.user not in MEMBERS.get(actor.tenant, set()):
        return False
    if doc["tenant"] != actor.tenant:
        return False
    return doc["published"] or actor.user in doc["readers"]


def evidence(actor, recipient=None):
    # A list replaces candidate retrieval; authorization precedes disclosure.
    return [doc["id"] for doc in DOCS if may_read(actor, doc)
            and (recipient is None or may_read(recipient, doc))]


mina = Actor("alder", "mina")
aria = Actor("alder", "aria")
print(evidence(mina))  # => ['help', 'mina-ticket']
print(evidence(aria))  # => ['help', 'mina-ticket', 'noor-ticket']
print(evidence(aria, mina))  # => ['help', 'mina-ticket']
MEMBERS["alder"].remove("aria")
print(evidence(aria, mina))  # => []

Run it in an isolated local interpreter. Then add an unpublished staff-only note and an unknown actor. Predict the result before changing the fixture. The note must not enter Mina's customer draft, and the unknown actor must receive no records. These are behavioral expectations, not a claim that this miniature function is production-ready.

The OWASP authorization cheat sheet is the reference for default denial and checking object permissions on each request. Our recipient check adds a policy specific to the support workflow.

Revocation has a timeline

Consider three moments: evidence selected, model request sent, answer delivered. If access is revoked between selection and delivery, a final permission check can block delivery but cannot undo disclosure to a processor that already received the prompt. Define which revocation guarantees the product requires at each boundary. Sensitive workflows may need shorter-lived work, current checks before dispatch and cancellation of queued results when policy changes.

Test a missing or unavailable authorizer as well as a denied record. Falling back to an old permissive cache entry converts an outage into a confidentiality failure. An acceptable degraded mode for this case is published-help-only answers, if that mode has a separate verified access path; otherwise return an unavailable result.

For caches, include tenant, actor, task, recipient and relevant policy/content versions where the output depends on them. Reauthorize or invalidate when grants change. A long-lived cache with a detailed key can still serve an obsolete answer. Revocation must also cover conversation summaries, citation previews, exports and background jobs.

Do this before moving on

Build a table with six cases: another tenant, another customer in the same tenant, an unpublished article, a revoked staff grant, an old cached answer and a queued draft whose recipient changed. For each, record the expected evidence set and the last permissible delivery decision.

Use the example for the first four. For the cache and queue cases, write the timeline and identify what a pure function cannot test. A complete answer names the integration test and the component that owns cancellation or reauthorization. Test only synthetic records in a system you own or are authorized to assess.

Go deeper

Key takeaways

  • Actor, task and recipient determine which evidence belongs in a context.
  • Search scoping and current object authorization solve different problems.
  • Cache separation does not establish permission freshness.
  • State revocation guarantees separately for selection, processor dispatch and final delivery.

Check yourself

Say or write your answer first, then reveal. Explaining it from memory, in your own words, is the skill an interviewer is checking.

  1. 1A search service retrieves candidates internally, then applies an unavoidable current permission check before any text reaches a model, trace or caller. Is post-filtering alone evidence of a leak?

  2. 2Aria’s grant is revoked after a prompt was sent but before its draft is delivered. What can a final access check accomplish?

  3. 3The response-cache key includes tenant and user. What must the revocation test still verify?

Sign in to track which lessons you have finished.